12

如果我有一个基类,只有虚拟方法和基类的 2 个派生类,并且实现了这些虚拟方法。

我如何:

 // causes C2259
 BaseClass* base = new BaseClass[2];

 BaseClass[0] = new FirstDerivedClass;
 BaseClass[1] = new SecondDerivedClass;

或者:

// causes "base is being used without being initialized"
BaseClass* base;
// causes CC59 again
BaseClass* base = new BaseClass;

base[0] = FirstDerivedClass();
base[1] = SecondDerivedClass();

(或类似的东西)

...这样我就可以通过 s 访问BaseClasss 方法DerivedClass,但是通过指针和指针是DerivedClasss 的数组?

4

5 回答 5

12

您的数组类型错误:它存储BaseClass对象实例而不是指向它们的指针。由于BaseClass似乎是抽象的,编译器抱怨它不能默认构造实例来填充你的数组。

即使BaseClass不是抽象的,在 C++ 中多态地使用数组也是一个很大的禁忌,所以在任何情况下你都应该做不同的事情。

通过将代码更改为:

BaseClass** base = new BaseClass*[2];

base[0] = new FirstDerivedClass;
base[1] = new SecondDerivedClass;

也就是说,在大多数情况下,最好使用std::vector普通数组和智能指针(例如std::shared_ptr)而不是哑指针。使用这些工具而不是手动编写代码将以极低的运行时成本透明地处理许多问题。

于 2012-10-24T11:33:59.577 回答
5

它是 C++ 使用std::vector而不是简单的数组:

std::vector<BaseClass*> base;
base.push_back(new FirstDerivedClass());
base.push_back(new SecondDerivedClass());

注意到Kerrek SB最安全的方法是使用std::unique_ptr

std::vector<std::unique_ptr<BaseClass> > base;
base.push_back( std_unique_ptr<BaseClass>(new FirstDerivedClass()) );
base.push_back( std_unique_ptr<BaseClass>(new SecondDerivedClass()) );
于 2012-10-24T11:31:31.017 回答
2

如果您的 BaseClass 包含纯虚拟方法,则将无法编译:

BaseClass* base = new BaseClass[2];

如果没有,您将获得内存泄漏。

在 c++ 中,这是通过使用带有某种智能指针的 std::vector 或 std::array 来完成的。例如 :

std::vector< std::shared_ptr< BaseClass > > arr( 2 );
arr[0].reset( new FirstDerivedClass() );
arr[1].reset( new SecondDerivedClass() );
于 2012-10-24T11:36:58.297 回答
0

这就是答案(来自鲁比)

BaseClass* Base[2];

Base[0] = new FirstDerivedClass;
Base[1] = new SecondDerivedClass;
于 2012-10-24T11:43:24.133 回答
0

定义一个指针数组,指针类型为BaseClass。并将派生类的指针分配给数组的元素。就像:

BaseClass* base [2];
base[0] = new FirstDerivedClass;
base[1] = new SecondDerivedClass;
于 2012-10-24T11:45:49.207 回答