c++基类包含派生类的实例
c++ base class contain instance of a derived class
我想知道是否有人可以向我解释我如何能够实现类似的东西:
namespace advanced_cpp_oop
{
class A
{
B b;
};
class B : public A
{
};
}
int main()
{
}
基类的实例可以包含派生类的实例?当编译上述代码时,会产生以下错误:
g++ advanced_cpp_oop.cpp
advanced_cpp_oop.cpp:8:5: error: ‘B’ does not name a type
可以编译的(几乎)等价的Java代码是:
public class AdvancedCppOop
{
public static void main(String[] args)
{
A a;
}
}
class A
{
B b;
}
class B extends A
{
}
谢谢
你需要添加一个指针和一个前向声明:
namespace advanced_cpp_oop
{
class B;
class A
{
B* b;
};
class B : public A
{
};
}
在你的c++代码中,你正在class A
中创建class B
的实例,这是不可能的,因为编译器还不知道class B
的任何东西(特别是不知道大小)。
从我的答案的代码,你需要动态分配class B
的实例,并将其分配给b
指针在你的代码的其他地方。
您必须使用某种类型的指针(例如unique_ptr)和前向声明:
class B;
class A
{
std::unique_ptr<B> b;
};
class B : public A
{
};
这是愚蠢的,你应该重新考虑你的设计。
c++和Java之间有一个非常重要的区别。c++是一种具有值语义的语言,而Java是一种具有引用语义的语言。在Java中创建非基本类型的变量时,创建的不是该类型的对象,而是对该对象的引用。相反,在c++中,相同的构造指的是一个实际的对象。
如果你记住这一点,就很容易理解为什么下面的代码不可能工作:
class Base {
Derived d;
};
class Derived : Base {};
c++中的第一个定义意味着对象Base在内部(不是通过引用)包含一个派生类型的对象。同时,派生类通过继承的方式包含了基类型的子对象。
这意味着派生类包含一个基类,而基类又包含一个派生类包含一个基类…Base或Derived的大小是多少?
在具有引用语义的语言中,或者在c++中使用指针,这不是问题。Base对象包含指向Derived的引用/指针。派生类通过继承方式包含基子对象。Base的大小是众所周知的:所有其他字段加上引用/指针的大小。派生类的大小等于Base类的大小加上添加的任何额外成员
Andreas比我先给出了正确的答案,但我要补充的是,Java代码之所以有效,只是因为Java对象是由指针隐式保存的(因此在Java代码中散布着B b = new B(...);
语句),即使它看起来不像。您的原始c++代码无法工作(即使添加了类B的前向声明),因为编译器不知道B对象有多大,因此不知道包含它的a对象将有多大。另一方面,所有指针都有相同的大小(不管指向类型是什么),所以当您用指向类a中的B对象的指针替换B对象时,编译器不会出现这样的问题。
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 如何检查派生类的类型?(C++实例)
- 从基类实例调用派生类方法而不进行强制转换
- 为什么派生类的实例从基类调用方法?
- 将基本实例指针强制转换为派生实例指针是否合法?(实例不是派生实例)
- 从模板基类派生是否在派生类声明的点实例化模板
- 根据参数创建派生类的新实例
- 派生模板类对象的实例化
- 是否可以从派生类返回基类的实例?
- 为什么不能在实例化对基类的引用的同时实例化指向派生类的指针?
- 无法实例化抽象类,但类不是抽象/派生方法的参数
- 选择专用于派生实例的基类的类模板
- 无法从派生类型的作用域访问另一个实例的受保护成员
- 在C++中,为什么仅包含与其基类实例的联合的派生类占用的内存多于联合的大小?
- 为什么我无法使用受保护/私有继承访问派生实例中基类的受保护成员?
- 为什么C++可以使用派生结构来实例化其父模板结构,而父模板可以调用子结构的函数?
- 使用单一实例类作为派生类时,如何访问基类中的函数
- 为什么模板名称在派生类中可用(基类是模板的实例)?
- 从类实例派生的类