2014-09-02 65 views
1

我有兩個類C++一個多態對象

class A { C* c; } 

class B { D* d; } 

,找到我需要構造一個std ::向量,其元素爲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; 

所有給我的編譯器錯誤:

「無效*」不是一個指針到對象類型

如何說服它的行的編譯器引用一個,如果我知道oPtr的類型是A *?

+2

'如果(測試 - > oType == 1)((A *)測試 - > OPTR) - > C' – nwp 2014-09-02 15:33:57

+2

爲什麼你使用'矢量'和'沒有向量'? – nwp 2014-09-02 15:34:54

+4

在C++中,多態性通常通過從一個公共基類繼承來表示。然後,通常嘗試使用虛擬方法而不是傳統的「if/then」結構來解決「對象類型選擇」問題。 – Galik 2014-09-02 15:37:26

回答

2

How do I convince the compiler that it's OK to reference a, if I know that the type of oPtr is A*?

嚴格地說,我認爲答案是:((A*)(test->oPtr))->a。在C++中這樣做的更好的方法是使用演員操作符:static_cast<A*>(test->oPtr)->a

但是這通常不是在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]; 
} 
+0

不會'static_cast (test-> oPtr) - > a'會更好嗎? – matsjoyce 2014-09-02 15:53:02

+0

@matsjoyce是的,你是對的。我會在中添加。 – Galik 2014-09-02 15:59:26

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函數。