为啥我不能如下设置接口类的成员变量

Posted

技术标签:

【中文标题】为啥我不能如下设置接口类的成员变量【英文标题】:Why can't i set a member variable of an interface class as follows为什么我不能如下设置接口类的成员变量 【发布时间】:2010-02-25 06:06:37 【问题描述】:

所以我有一个接口类

class interfaceClass

 public:   
    virtual void func1( void ) = 0;
    virtual void func2( void ) = 0;

protected:
    int m_interfaceVar;

以及从它继承的类。 为什么不能如下设置接口类的成员变量。

class inhertitedClass : public interfaceClass

   inheritedClass(int getInt): m_interfaceVar(getInt);
   ~inheritedClass();

我必须这样做

class inhertitedClass : public interfaceClass

   inheritedClass(int getInt) m_interfaceVar = getInt;
   ~inheritedClass();

如果这是一个愚蠢的问题,我很抱歉,但我前几天晚上在将抽象类切换到接口类(返回到抽象类)时遇到了这个问题。

【问题讨论】:

我什至可以在接口类中有一个变量吗?太久没写了。 我试图访问的变量初始化错误。 该成员变量不属于该类。由于所有方法都是抽象的,因此没有任何理由不将其移至派生类。 【参考方案1】:

构造函数中的初始化列表可以首先为基类指定ctor。通过剥夺interfaceClass 的(受保护的)构造函数(它显然应该拥有)你已经切断了这条生命线。

所以添加受保护的ctor,例如:

class interfaceClass

 public:   
    virtual void func1( void ) = 0;
    virtual void func2( void ) = 0;

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

那么你可以用正确的方式做事,即

class inhertitedClass : public interfaceClass

   inheritedClass(int getInt): interfaceClass(getInt);
   ~inheritedClass();

【讨论】:

【参考方案2】:

inheritedClass 到达它的初始化列表时,m_interfaceVar 已经被初始化了。你不能再次初始化它。

您的选择是为interfaceClass 提供一个初始化m_interfaceVar 的构造函数,或者只是在inheritedClasss 构造函数的主体中分配它:

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

 inheritedClass(int getInt)
 
    m_interfaceVar = getInt;
 

【讨论】:

我认为接口类不应该有构造函数? C++ 中的抽象类没有什么特别之处,只是不能直接创建抽象类的实例。事实上,如果你不提供构造函数,编译器会为你填写一些。 @Craig:一个接口不应该是直接可实例化的,所以它不应该有一个 public 构造函数。 如果一个类有成员属性,它们应该被初始化并且这样的构造函数是合适的(除非默认构造函数就足够了) @Scott Smith:如果该类具有纯虚方法,则它不能被任何实例化,除非派生类覆盖这些虚方法。现在,代码缺少的一件事是具有受保护的析构函数或公共虚拟析构函数,具体取决于预期的用法。【参考方案3】:

试试这样:

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();

...事实上,如果您interfaceClass 创建一个受保护的或私有的构造函数,编译器会默默地为您创建一个,用户将能够创建你的接口(你确实希望它是一个抽象基类,对吧?)

【讨论】:

用户无论如何都不能创建接口的实例:纯虚方法使类抽象,你不能实例化抽象类。将构造函数设为 public 或 protected 并不会产生任何影响。

以上是关于为啥我不能如下设置接口类的成员变量的主要内容,如果未能解决你的问题,请参考以下文章

子类能继承父类的哪些变量和方法

JAVA接口中成员变量必须是final类型的,为啥

为啥我可以在 Qt 5.5.1 中使用 QSerialPort* 作为临时变量而不是作为类的成员?

为啥我不能更改 unordered_map 返回的对象的成员变量?

为啥这个 const auto 变量在 range-for 循环中为类的 const 成员函数编译?

子类能不能继承父类的成员变量