C ++在多态对象中引用

时间:2014-09-02 15:29:58

标签: c++ polymorphism

我有两个班级

class A { C* c; }

class B { D* d; }

并且发现我需要构造一个std :: vector,其元素是A或B(在运行时决定序列。所以我构造了一个多态

class Poly {
    int   oType;
    void* oPtr;
}

以及构造函数

Poly::Poly(int type)
{
    if (type == 1) oPtr = new (A*) oPtr();
    if (type == 2) oPtr = new (B*) oPtr();
    oType = type;
}

以及类似结构的析构函数。现在

std::vector<Poly*> test;

的工作原理。但是,我无法访问子对象。

我试过

if (test->oType == 1) test->oPtr->a;

if (test->oType == 1) test->(A*)oPtr->a;

if (test->oType == 1) (A*)(test->oPtr)->a;

所有给我编译错误:

'void *'不是指向对象的指针类型

如果我知道oPtr的类型是A *,我如何说服编译器引用a是可以的?

2 个答案:

答案 0 :(得分:2)

  

如果我知道的话,我如何说服编译器引用它是可以的   oPtr的类型是A *?

我认为答案是:((A*)(test->oPtr))->a。在C ++中更好的方法是使用强制转换运算符:static_cast<A*>(test->oPtr)->a

HOWEVER 这通常不是如何在c ++中解决此问题。所以我提供了一种更常用的方法,你可能会发现它很有用:

class Poly
{
public:
    virtual ~Poly() {}
    virtual void do_something() = 0; // each sub-type has its own version of this
};

class A: public Poly
{
public:
    void do_something() /* override */ // c++11 only
    {
        std::cout << "Doing something A specific\n";
    }
};

class B: public Poly
{
public:
    void do_something() /* override */ // c++11 only
    {
        std::cout << "Doing something B specific\n";
    }
};

int main()
{
    std::vector<Poly*> polys;

    // create data structure
    polys.push_back(new A);
    polys.push_back(new A);
    polys.push_back(new B);
    polys.push_back(new A);

    // use objects polymorphically
    for(size_t i = 0; i < polys.size(); ++i)
        polys[i]->do_something();

    // clean up memory (consider using 'smart pointers')
    for(size_t i = 0; i < polys.size(); ++i)
        delete polys[i];
}

答案 1 :(得分:0)

正如其他人提到的,多态方式是使用虚函数。

这是使用智能指针的实现。创建者类负责创建我们要求的Poly对象。这将创建隔离到一个类。

请注意,有更复杂的方法可以做到这一点。这里的目标是或多或少地展示如何使用C ++完成它。

#include <vector>
#include <memory>
#include <iostream>

class Poly 
{   
    public:
        virtual void Test() = 0; 
};

typedef std::unique_ptr<Poly> PolyPtr;

class A : public Poly
{
    public:
        void Test() { std::cout << "Test for A" << "\n"; }
};

class B : public Poly
{
    public:
        void Test() { std::cout << "Test for B" << "\n"; }
};

class PolyCreator
{
    public:
        PolyPtr CreatePolyObject(int oType)
        {
            switch( oType )
            {
                case 1: 
                    return PolyPtr(new A());
                case 2: 
                    return PolyPtr(new B());
            }
            throw "Could not find type in list";
        }
 };

 int main()
 {
     PolyCreator pCreator;
     std::vector<PolyPtr> PolyPtrVect;

     // create objects
     PolyPtrVect.push_back(pCreator.CreatePolyObject(1));
     PolyPtrVect.push_back(pCreator.CreatePolyObject(2));

     // call Test functions for each
     std::vector<PolyPtr>::iterator it = PolyPtrVect.begin();
     while ( it != PolyPtrVect.end())
     {
         (*it)->Test();
         ++it;
     }
 }

输出:

Test for A
Test for B

注意

  1. 只有一个if()语句与PolyCreator类隔离。
  2. 由于使用std::unique_ptr而没有内存泄漏。
  3. Poly是一个抽象类。所有派生类都必须实现Test函数。