views:

215

answers:

3

So i have a interface class

class interfaceClass
{
 public:   
    virtual void func1( void ) = 0;
    virtual void func2( void ) = 0;

protected:
    int m_interfaceVar;
}

and a class that inherits from it. Why can't i set the member variable of the interface class as follows.

class inhertitedClass : public interfaceClass
{
   inheritedClass(int getInt): m_interfaceVar(getInt){};
   ~inheritedClass(){};
}

and i have to do it like this

class inhertitedClass : public interfaceClass
{
   inheritedClass(int getInt){ m_interfaceVar = getInt;}
   ~inheritedClass(){};
}

I'm sorry if this is a dumb question, but i just ran in to it the other night while i was switching my abstract class into an interface class (the back to an abstract class).

+5  A: 

By the time inheritedClass gets to it's initializer list, m_interfaceVar has already been initialized. You can't initialize it a second time.

Your options are to provide a constructor to interfaceClass that initializes m_interfaceVar, or just assign it in the body of inheritedClasss constructor:

 interfaceClass(int getInt) : interfaceVar(getInt){}
 ...
 inheritedClass(int getInt) : interfaceClass(getInt)
 {
 }

or

 inheritedClass(int getInt)
 {
    m_interfaceVar = getInt;
 }
Eclipse
i thought interface classes shouldn't have constructors?
Craig
There's nothing special about abstract classes in C++ except that you can't directly create an instance of one. In fact, if you don't provide a constructor, the compiler will fill some in for you.
Eclipse
@Craig: An interface shouldn't be directly instantiable, so it shouldn't have a *public* constructor.
Scott Smith
If a class has member attributes, they should be initialized and as such a constructor is appropriate (unless the default constructor suffices)
David Rodríguez - dribeas
@Scott Smith: If the class has pure virtual methods, it cannot be instantiated anyway by any but deriving classes that override those virtuals. Now, the one thing that the code is missing is having a protected destructor or a public virtual one, depending on the expected usage.
David Rodríguez - dribeas
A: 

Try it like this:

class interfaceClass
{
public:   
    virtual void func1( void ) = 0;
    virtual void func2( void ) = 0;

protected:
    // Ctor - called from derived classes
    interfaceClass(int interfaceVar)
        : m_interfaceVar(interfaceVar){};

    int m_interfaceVar;
}

class inhertitedClass : public interfaceClass
{
   inheritedClass(int getInt)
       : interfaceClass(getInt){}; // Pass to base class ctor

   ~inheritedClass(){};
}

...in fact, if you don't create a protected or private constructor for interfaceClass, the compiler will silently create one for you, and users will be able to create instances of your interface (you did want it to be an abstract base class, right?)

Scott Smith
Users will not be able to create instances of the interface anyway: pure virtual methods make the class abstract and you cannot instantiate an abstract class. Havint the constructor public or protected will not actually make any difference.
David Rodríguez - dribeas
+4  A: 

The initializer list in a constructor can specify the ctor for the base classes first and foremost. By depriving interfaceClass of a (protected) constructor (which it obviously should have) you've cut off that lifeline.

So add that protected ctor, e.g.:

class interfaceClass
{
 public:   
    virtual void func1( void ) = 0;
    virtual void func2( void ) = 0;

protected:
    int m_interfaceVar;
    interfaceClass(int x) { m_interfaceVar=x; }
}

and then you can do things the right way, namely

class inhertitedClass : public interfaceClass
{
   inheritedClass(int getInt): interfaceClass(getInt){};
   ~inheritedClass(){};
}
Alex Martelli