条件c ++中对象的实例化

时间:2010-10-30 07:48:34

标签: c++

假设我想根据特定情况实例化不同类型的对象,所以我会在if语句的主体内实例化它们。问题是如果您想稍后使用该对象,则需要在实例化之前声明它。如何声明一个通用对象。是否有类似Java中的对象类?

我做了一些谷歌搜索,如“通用对象c ++”和“对象类c ++”,似乎没有类似的东西。

6 个答案:

答案 0 :(得分:4)

这个问题可以用接口来解决。现在,C ++不知道接口,但您可以轻松地使用抽象基类做类似的事情:

class Base { ... }
class A : public Base { ... }   // A is a Base
class B : public Base { ... }   // B is a Base

...

Base *X;                        // that's what you will end up using

if (some_condition)
    X = new A();                // valid, since A is a Base
else
    X = new B();                // equally valid, since B is a Base

这将要求您将常用功能放入基类中,以便您可以在X上实际执行操作。

(如果你从Base之类的东西派生出你的所有类,你最终会得到像C#或Java那样的超类。但是,在我看来,通用编程,即模板在C ++中,大大减少了对类似超类的需求。我敢打赌,在大多数情况下,你将能够找到更好的代码设计。)

答案 1 :(得分:3)

与Java不同,C ++没有所有类继承的“母”对象。为了完成你所说的,你需要使用你自己的类层次结构的基指针。

Animal* a;
if (...) a = new Cat();
else if (...) a = new Dog();

另外,因为没有垃圾收集,所以当你做这类事情时最好使用智能指针。否则,请务必记得delete a。您还需要确保Animalvirtual destructor

答案 2 :(得分:2)

C ++中没有“所有类的祖先”。但是有一些选择可以做类似的事情。

正如stakx建议的那样,如果可能的话,建立一个基类。从面向对象的设计角度来看,这是最好的。是否存在要应用于所有对象的常见操作?如果是这样,请尝试编写接口,并使接口成为基类。或者,您可以使用模板来获取编译时多态性,而不是运行时多态性。

如果这太难了,那么看一下像boost::any这样的包装类。这可以保存任何(可复制)类型。它是一个不透明的包装器,您必须知道放入其中的完全类型的数据,才能将其取回。例如,如果您输入Derived *,则需要使用boost::any_cast<Derived *>(wrapped)来获取数据 - boost::any_cast<Base *>(wrapped)将无效。

答案 3 :(得分:1)

std::shared_ptr<Base> X( some_condition ? new A() : new B() ); 

答案 4 :(得分:1)

堆解决方案昂贵且容易出错。对于没有构造堆分配的太重的对象,以下方法是可取的:

Derived1 d1;
Derived2 d2;
Base * b = 0;

if (useD1) {
  b = &d1;
} else {
  b = &d2;
}

这里我们分配我们在堆栈上可能需要的两种类型。没有堆分配,没有删除操作符,没有智能指针。唯一的问题 - 不能扩展到要预先分配的复杂类。

答案 5 :(得分:0)

C ++中没有通用的基类,所以如果你是这些类的作者,你应该自己定义这样的共同祖先,或者你可以使用void *虽然我不推荐后者。

如果您无法修改类,那么您可以引入实现所需接口的包装器,如下所示:

class A {};
class B {};

class MyBase
{
    // Define the interface that you need.
};

class MyA : public MyBase
{
private:
    A a;
public:
    // Implement MyBase in terms of A.
};

class MyB : public MyBase
{
private:
    B b;
public:
    // Implement MyBase in terms of B.
};

int main ()
{
    MyBase* base = 0;
    if (useA)
        base = new MyA();
    else
        base = new MyB();
}