2011-04-16 36 views
5

Cố gắng tạo lớp loại Trình điều khiển ở nơi, bên dưới, Cơ sở là Trình điều khiển được truyền qua loại lúc khởi tạo. Loại, 2 trong trường hợp này, được sử dụng để xây dựng đối tượng có nguồn gốc chính xác.Khởi tạo đối tượng có nguồn gốc từ lớp Cơ sở

Trình biên dịch của tôi đang ném một lỗi cú pháp khai báo trên dòng "Lớp cơ sở".

mục tiêu cuối cùng của tôi là để có thể làm điều này:

Base *B; 

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

Đây là mã của tôi rằng sẽ không biên dịch ...

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"); 
} 

Dưới đây được cập nhật mã để hiển thị các nguồn đầy đủ . Tôi nghĩ rằng bây giờ tôi hiểu tại sao nó sẽ không biên dịch. Như được chỉ ra bên dưới, tôi có một chuỗi cuộc gọi vô tận tới 'mới'

#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

Nội dung của lỗi là gì? Nếu nó đề cập đến dòng đầu tiên của đoạn mã của bạn, điều đó không * nhìn * sai. – ssube

+2

Còn thời gian chạy thì sao? Khi bạn tạo một Base (1), hàm tạo tạo một Derived mới, gọi là lớp cơ sở của nó, Base (1), tạo ra một Derived mới, gọi là lớp cơ sở của nó ... –

+0

@Eric: hãy sử dụng một trong hai std :: unique_ptr', 'boost :: scoped_ptr' hoặc' std :: auto_ptr' (sau này trở nên tệ hơn). Bạn bị rò rỉ bộ nhớ trong mẫu đồ chơi của mình:/ –

Trả lời

2

Có vẻ như bạn đang cố gắng thực hiện class factory.

Tôi khuyên bạn nên có phương pháp tĩnh trong Cơ sở trả về Derived1 hoặc 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

điều này thật thú vị, tôi có thể đọc/hiểu điều này nhưng tôi vẫn gãi đầu vì sao mã của tôi không biên dịch? Điều này cuối cùng không trả lời câu hỏi của tôi. Tôi không muốn người gọi phải biết chi tiết về Base :: Create. Tôi muốn người gọi chỉ cần gọi Base (loại) mới nếu điều đó là có thể? – Eric

+0

Đầu tiên, mã của bạn đang cố gắng gọi các hàm mà nó chưa khai báo, bạn sẽ phải thực hiện các phương thức proxy gọi các đối tác của chúng trong hHandle. Thứ hai, và đáng chú ý nhất là không bị bắt bởi trình biên dịch, việc tạo ra Derived1 sẽ gọi hàm dựng cơ sở để tạo một thể hiện khác của Derived1 trong một vòng lặp vô tận. –

+0

Bỏ qua phần đầu tiên của nhận xét cuối cùng ... Nếu lớp Cơ sở có lỗi cú pháp, có thể do dấu chấm phẩy bị thiếu ở trên, có thể trong tệp bao gồm. Tôi thấy không có gì sai với dòng đó. Bạn có thể sửa lỗi đầy đủ từ trình biên dịch không? –

Các vấn đề liên quan