2011-04-16 220 views
5

试图创建一个驱动程序类型类,其中,下面的Base是在实例化时传递类型的驱动程序。在这种情况下,类型2用于构造正确的派生对象。从基类实例化派生对象

我的编译器在“Class Base”行上抛出了一个Declaration语法错误。

我的最终目标是能够做到这一点:

Base *B; 

    B = new Base(2); 
    if(B) 
    { 
     B->DoStuff(); 
     B->DoMoreStuff(); 
     delete B; 
    } 

这里是我的代码将无法编译...

class Base 
{ 
public: 

    Base(int h); 
    virtual ~Base(); 

private: 
    int hType; 
    Base *hHandle; 
}; 


class Derived1 : public Base 
{ 
public: 
    Derived1(); 
    virtual ~Derived1(); 

}; 

class Derived2 : public Base 
{ 
public: 
    Derived2(); 
    virtual ~Derived2(); 

}; 

Base::Base(int h) 
{ 
    hType = h; 

    switch(h) 
    { 
     case 1: 
      hHandle = new Derived1; 
     break; 

     case 2: 
      hHandle = new Derived2; 
     break; 

    } 
} 


Derived1::Derived1():Base(1) 
{ 
    printf("\nDerived1 Initialized\n\n"); 
} 

Derived2::Derived2():Base(2) 
{ 
    printf("\nDerived2 Initialized\n\n"); 
} 

下面是更新后的代码,以显示完整的源代码。我想我现在明白为什么它不会编译。正如下面指出的,我有一个无限循环呼叫'新'

#include <stdio.h> 

class Base 
{ 
public: 

    Base(); 
    Base(int h); 
    Create (int h); 
    virtual ~Base(); 

private: 
    int hType; 
    Base *hHandle; 
}; 


class Derived1 : public Base 
{ 
public: 
    Derived1(); 
    virtual ~Derived1(); 

}; 

class Derived2 : public Base 
{ 
public: 
    Derived2(); 
    virtual ~Derived2(); 

}; 

Base::Base() 
{ 

} 

Base::Base(int h) 
{ 
    Create(h); 
} 

Base::Create(int h) 
{ 
    hType = h; 

    switch(h) 
    { 
     case 1: 
      hHandle = new Derived1; 
     break; 

     case 2: 
      hHandle = new Derived2; 
     break; 

    } 
} 

Derived1::Derived1() 
{ 
    printf("\nDerived1 Initialized\n\n"); 
} 

Derived2::Derived2() 
{ 
    printf("\nDerived2 Initialized\n\n"); 
} 
+0

错误的文字是什么?如果它指的是你的代码片段的第一行,那不*看*错误。 – ssube 2011-04-16 03:19:49

+2

运行时怎么样?当你创建一个Base(1)时,构造函数创建一个新的Derived,它调用它的基类Base(1),它创建一个新的Derived,它调用它的基类... – 2011-04-16 10:48:47

+0

@Eric:请使用'std :: unique_ptr','boost :: scoped_ptr'或'std :: auto_ptr'(后者更糟糕)。你的玩具样品有内存泄漏:/ – 2011-04-16 14:18:36

回答

2

它看起来像你试图做class factory

我建议你在Base中有一个返回Derived1或Derived2的静态方法。

class Base 
{ 
public: 
    static Base* Create(int); 
    virtual void DoStuff() = 0; 
} 

class Derived1 : public Base 
{ 
    Derived1() 
    { 
     printf("\nDerived1 Initialized\n\n"); 
    } 

    virtual void DoStuff() 
    { 
    } 
} 

class Derived2 : public Base 
{ 
    Derived2() 
    { 
     printf("\nDerived2 Initialized\n\n"); 
    } 

    virtual void DoStuff() 
    { 
    } 
} 

Base* Base::Create(int n) 
{ 
    if (n==1) 
     return new Derived1(); 
    else if (n==2) 
     return new Derived2(); 
    else 
     return nullptr; 
} 

void main() 
{ 
    Base* B = Base::Create(2); 
    if(B) 
    { 
     B->DoStuff(); 
     delete B; 
    } 
} 
+0

这很有趣,我可以阅读/理解这一点,但我仍然在摸索为什么我的代码不能编译?这最终不能回答我的问题。我不希望调用者必须知道Base :: Create的细节。如果可能的话,我希望调用者只需调用新的Base(类型)? – Eric 2011-04-16 02:58:17

+0

首先,你的代码试图调用它没有声明的函数,你必须在hHandle中调用它们的代理方法。其次,最值得注意的是不会被编译器捕获,Derived1的创建将调用Base构造函数在无限循环中创建另一个Derived1实例。 – 2011-04-16 04:33:56

+0

忽略最后一个注释的第一部分...如果Base Base有语法错误,可能是由于上面缺少分号,可能是包含文件。我认为这条线没有错。你能否提供编译器的完整错误? – 2011-04-16 04:42:01