Thread: Abstract Base Class and References

  1. #1
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681

    Abstract Base Class and References

    Ok given a class that is abstract due to a pure virtual function you can not have an instance of that class. However you can have a pointer of that type. Now that I'm cool with. What he is trying to say is that you can not have a reference of that type either. This is what I have a problem with. So I decided to test it out:

    base.h:
    Code:
    #ifndef MYBASE_H_
    #define MYBASE_H_
    #include <iostream>
    class mybase {
      int x;
      int y;
      public:
        inline mybase() : x(0), y(0) {}
        virtual ~mybase() {}
    
        virtual void sayhi() = 0;
    
        friend std::ostream & operator << (std::ostream &, const mybase &);
    };
    #endif
    base.cpp
    Code:
    #include <iostream>
    #include "base.h"
    std::ostream & operator << (std::ostream &out, const mybase &par)
    {
      return out<<"Base object: "<< par.x << " " << par.y << endl;
    }
    dir.h
    Code:
    #ifndef DIR_H_
    #define DIR_H_
    #include "base.h"
    
    class dir : public mybase
    {
      int z;
      public:
        dir () : z(10) {}
        inline dir operator + () { return *this; }
        virtual void sayhi() { cout<<"Hello"; }
    };
    
    #endif
    main.cpp
    Code:
    #include "dir.h"
    
    int main()
    {
      dir mydir;
      cout<<mydir<<endl;
      mydir.sayhi();
      cout<<mydir<<endl;
    }
    Note: Yes I know I forgot some namespaces on cout and endl.

    Ok now this compiled and ran as I expected with g++ with the options: -Wall -ansi -pedantic -g

    Now this seems to me to indicate that you can have a reference to an abstract class.

    Anyone care to comment? (Heres looking at you Sang-drax )

    Mostly I need to know if there is some flaw in my test code that is allowing me to do something I'm not suppose to do and/or I'm just misinterpting what I see

  2. #2
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Quote Originally Posted by Thantos
    What he is trying to say is that you can not have a reference of that type either.
    This is from ISO C++ standard:

    "An abstract class is a class that can be used only as
    a base class of some other class; no objects of an abstract class
    can be created except as sub-objects of a class derived from it.
    A class is abstract if it has at least one pure virtual function.
    [Note: such a function might be inherited: see below. ]
    A virtual function is specified pure by using a pure-specifier
    in the function declaration in the class declaration.
    A pure virtual function need be defined only if explicitly
    called with the qualified-id syntax."

    Code:
    class point { /* ... */ };
    class shape {                   //  abstract class
        point center;
        //  ...
    public:
        point where() { return center; }
        void move(point p) { center=p; draw(); }
        virtual void rotate(int) = 0;       //  pure virtual
        virtual void draw() = 0;            //  pure virtual
        //  ...
    };

    "An abstract class shall not be used as a parameter type, as
    a function return type, or as the type of an explicit conversion.
    Pointers and references to an abstract class can be declared. "
    Example:

    Code:
    shape x;                        //  error: object of abstract class
    shape* p;                       //  OK
    shape f();                      //  error
    void g(shape);                  //  error
    shape& h(shape&);               //  OK

  3. #3
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    I found more informations:

    An abstract class provides an interface and other concrete class provides implementation details.
    Here's what I found in the C++ programming language:

    "However, a programmer sometimes wants to output an object for which only a base class is known.
    Since the exact type isn’t known, correct output cannot be achieved simply by defining a << for each new type. Instead, a virtual output function can be provided in the abstract base:
    Code:
    class My_base {
    public:
    / / ...
    virtual ostream& put(ostream& s) const = 0; / / write *this to s
    };
    ostream& operator<<(ostream& s, const My_base& r)
    {
    	return r.put(s) ; / / use the right put()
    }
    That is, put() is a virtual function that ensures that the right output operation is used in <<.
    Given that, we can write:
    Code:
    class Sometype : public My_  base {
    public:
    / / ...
    ostream& put(ostream& s) const; / / the real output function: override My_base::put()
    };
    void f(const My_  base& r, Sometype& s) / / use << which calls the right put()
    {
    	cout << r << s;
    }
    This integrates the virtual put() into the framework provided by ostream and <<. The technique
    is generally useful to provide operations that act like virtual functions, but with the runtime
    selection
    based on their second argument."

    Consider this simple example:
    Code:
    #include <iostream>
    using namespace std;
    
    class mybase
    {
    public:
    	mybase()
    	{
    		cout<<"\nBase constructor called!\n";
    	}
    	virtual void func()=0;
    	virtual ~mybase()
    	{
    		cout<<"\nBase destructor called!\n";
    	}
    };
    
    class derived : public mybase
    {
    	int x;
    public:
    	derived()
    	{
    		cout<<"\nDerived constructor called!\n";
    	}
    	virtual void func()
    	{
    		cout<<"Hello there";
    	}
    	~derived()
    	{
    		cout<<"\nDerived destructor called!\n";
    	}
    };
    int main()
    {
      derived d;
      mybase& f=d;
    }
    As you can see first base constructor is called and then derived constructor is called.

    so with a little help of Thinking in C++ we can conclude why we can have reference of an abstract class:

    "
    Note that pure virtual functions prevent an abstract class from being passed into a function by value. Thus, it is also a way to prevent object slicing"

    A more informations about object slicing and about abstract class in general cand be found in Thinking in C++ and that can be freely downloaded from www.bruceeckel.com

    I hope this helps!
    Cheers
    Micko
    Last edited by Micko; 10-13-2004 at 06:43 AM.

  4. #4
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    What is the section you quoted from the ISO Standard?

    NM was able to find a draft copy of the standard.

  5. #5
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Quote Originally Posted by Thantos
    Anyone care to comment? (Heres looking at you Sang-drax )
    Yes, you can have references to abstract classes, just like pointers.
    From what I can see, your test program is correct.
    Quote Originally Posted by Thantos
    What he is trying to say is that you can not have a reference of that type
    Who is "he"? The teacher of the class you're tutoring? I hope not.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  6. #6
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    He is the teacher of the C++ OOP class I'm taking
    I tutor Procedural C (with a little bit of C++)

    Well I sent him an email earlier with a link to a webpage with a draft copy of the standard, along with a quote from BS on why something like i = i++ + i++; is undefined. Hopefully he'll accept it and change his lectures (and hopfully the the fugly header we have to use for our next project)

  7. #7
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Quote Originally Posted by Thantos
    He is the teacher of the C++ OOP class I'm taking
    Jesus.
    The final version of the standard was released in, what, 1998?
    And I'm sure it has been legal to declare references to abstract classes far longer than those six years.

    And the famous i++ + ++i... do you remember the debate with Mister C? It's the funniest thread I've read during my time as a member here.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  8. #8
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Ah yes I remember that thread. I piped up during that part of the lecture and explained what the standard said, though when it came time for the test I gave him the answer he wanted.

    I don't remember the exact year of the standard but '98 sounds right. He said he first year of teaching was '00 and he hasn't worked the industry between getting his masters and starting teaching. Hmmm I guess I'll run to kinko's and have a copy of the standard made with a pretty bow on it for him once I buy it

  9. #9
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Quote Originally Posted by Thantos

    I don't remember the exact year of the standard but '98 sounds right.
    Work on the ANSI/ISO C++ standard began in 1990. The committee issued some interim working papers in the following years. In April 1995 it released a Committee Draft (CD) for public comment. In December 1996 it released a second version (CD2) for further public review. These documents not only refined the description of existing C++ features but also extended the language with exceptions, RTTI, templates, and the Standard Template Library. The final International Standard (ISO/IEC 14882:1998) was adopted in 1998 by the ISO, IEC (International Electrotechnical Committee), and ANSI.
    The ANSI/ISO C++ standard additionally draws upon the ANSI C standard, because C++ is supposed to be, as far as possible, a superset of C. That means any valid C program ideally should also be a valid C++ program. There are a few differences between ANSI C and the corresponding rules for C++, but they are minor. Indeed, ANSI C incorporates some features first introduced in C++, such as function prototyping and the const type qualifier.

    Prior to the emergence of ANSI C, the C community followed a de facto standard based on the book The C Programming Language, by Kernighan and Ritchie (Addison-Wesley Publishing Company Reading, MA. 1978). This standard often was termed K&R C; with the emergence of ANSI C, the simpler K&R C now sometimes is called classic C.

    The ANSI C standard not only defines the C language, it also defines a standard C library that ANSI C implementations must support. C++ also uses that library; this book will refer to it as the standard C library or the standard library. In addition, the ANSI/ISO C++ standard provides a standard library of C++ classes.

    More recently, the C standard has been revised; the new standard, sometimes called C99, was adopted by ISO in 1999 and ANSI in 2000. The standard adds some features to C, such as a new integer type, that some C++ compilers support. Although not part of the current C++ standard, these features may become part of the next C++ standard.

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The old C standard was often called C89, because it became an ANSI standard in 1989, or C90, when it became an ISO standard.

    Also, both the C and C++ standards provide the conformance level of a "freestanding implementation", which does not include the standard library, I think.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Default class template problem
    By Elysia in forum C++ Programming
    Replies: 5
    Last Post: 07-11-2008, 08:44 AM
  2. Problems defining classes
    By esmeco in forum C++ Programming
    Replies: 47
    Last Post: 10-24-2007, 01:13 PM
  3. Some problems with an abstract class
    By DavidP in forum C++ Programming
    Replies: 8
    Last Post: 12-13-2006, 03:59 PM
  4. Predeclaration of template class in namespace
    By unregistred in forum C++ Programming
    Replies: 0
    Last Post: 05-30-2003, 03:52 AM
  5. Information Regarding Pure Virtual Functions
    By shiv_tech_quest in forum C++ Programming
    Replies: 6
    Last Post: 01-29-2003, 04:43 AM