C++ 在C++;如何仅为一个变量拥有内存在base&;中定义;派生类

C++ 在C++;如何仅为一个变量拥有内存在base&;中定义;派生类,c++,C++,若我们创建派生类的对象,是否可能只有一个变量(在基类和派生类中都定义)的内存。如果可以,原因是什么,请提供完整的解释 class Base { private: int i; } class derived: public /* or private or protected (whatever fits in my question) */ Base { private: int i; } int main() { derived obj; } 您真正想要的

若我们创建派生类的对象,是否可能只有一个变量(在基类和派生类中都定义)的内存。如果可以,原因是什么,请提供完整的解释

class Base
{
private:
    int i;
}

class derived: public /* or private or protected (whatever fits in my question) */
    Base
{
private:
    int i;
}

int main()
{
   derived obj;
}

您真正想要的是在母子类中访问相同的成员:

    class Base { protected: int i; }; // allow child class only to access i

class derived: public Base {  
    private:
    void blah() { i = 42; } // valid, we access a protectd 
};

我使用了公共继承,但它仍然适用于其他继承。

您真正想要的是在母类和子类中访问相同的成员:

    class Base { protected: int i; }; // allow child class only to access i

class derived: public Base {  
    private:
    void blah() { i = 42; } // valid, we access a protectd 
};

我使用了公共继承,但它仍然可以与其他继承一起使用。

如果父类中有变量,则不需要在子类中声明它。这就是衍生的部分含义;它继承父级的所有成员,包括任何变量。它只会在内存中使用一个点,并且只定义一次:在父级中。您只需要确保它在父类中定义为受保护的或公共的。

如果您在父类中有一个变量,则不需要在子类中声明它。这就是衍生的部分含义;它继承父级的所有成员,包括任何变量。它只会在内存中使用一个点,并且只定义一次:在父级中。您只需确保它在父类中定义为protected或public。

您可以将基类中的字段声明为protected,并且可以从派生类访问它

<>但是, >保护字段通常在C++世界中被禁止。最好将字段
设为私有
,并提供
受保护的
访问器方法(
get_i()
set_i()
或类似方法)


根据他的说法,比亚恩·斯特劳斯托普自己写道:

宣布受保护的成员比宣布为私人的成员更容易受到虐待。特别是,声明受保护的数据成员通常是一个设计错误。将大量数据放在一个公共类中供所有派生类使用会使该数据容易损坏。更糟糕的是,受保护的数据(如公共数据)无法轻松地进行重组,因为没有找到每个用途的好方法。因此,受保护的数据成为软件维护问题


有一个更微妙的观点,或者更确切地说,解释了何时保护字段可能是一个好主意。

您可以将基类中的字段声明为受保护的,并且可以从派生类访问它

<>但是, >保护字段通常在C++世界中被禁止。最好将字段
设为私有
,并提供
受保护的
访问器方法(
get_i()
set_i()
或类似方法)


根据他的说法,比亚恩·斯特劳斯托普自己写道:

宣布受保护的成员比宣布为私人的成员更容易受到虐待。特别是,声明受保护的数据成员通常是一个设计错误。将大量数据放在一个公共类中供所有派生类使用会使该数据容易损坏。更糟糕的是,受保护的数据(如公共数据)无法轻松地进行重组,因为没有找到每个用途的好方法。因此,受保护的数据成为软件维护问题


有一个更微妙的观点,或者更确切地说,解释了什么时候保护字段可能是一个好主意。

从您的评论到我学到的其他答案,您不想访问Base::I,您甚至希望它不存在

所以答案是:不,这是不可能的

造成这种情况的原因有很多:内存布局会复杂得多,多态性不会很好地工作,而且“切片”等“功能”也会中断

你为什么有这个要求?在本例中,您使用了一个int。在现实世界中,成员变量是一个大得多的对象,您是否遇到了问题?如果是这样,如果需要,可以使用指针动态创建对象。(在基类中使用公共构造函数和受保护的构造函数:公共构造函数创建基类对象,然后还使用new和受保护的构造函数创建成员变量,以从派生类的构造函数中调用)


无论如何:很可能您的类设计有问题:继承意味着“是”关联,所以通常基类的所有“属性”(=成员变量)都是派生类的一部分。

从您的注释到我了解到的其他答案,您不想访问base::I,您甚至希望它不存在

所以答案是:不,这是不可能的

造成这种情况的原因有很多:内存布局会复杂得多,多态性不会很好地工作,而且“切片”等“功能”也会中断

你为什么有这个要求?在本例中,您使用了一个int。在现实世界中,成员变量是一个大得多的对象,您是否遇到了问题?如果是这样,如果需要,可以使用指针动态创建对象。(在基类中使用公共构造函数和受保护的构造函数:公共构造函数创建基类对象,然后还使用new和受保护的构造函数创建成员变量,以从派生类的构造函数中调用)


无论如何:很可能您的类设计有问题:继承意味着“是”关联,因此通常基类的所有“属性”(=成员变量)也是派生类的一部分。

因为您使用的是私有数据成员,
i
s必须是单独的变量。如果
i
受到保护,则
derived
将能够毫无问题地使用
Base::i
。一般认为受保护的
通常是个坏主意,因为它需要在一个类中创建两个接口(一个用于其他类,一个用于子类),但是