2012-02-27 35 views
6

Ví dụ: trong chức năng chính, tôi muốn nhận dữ liệu nhập của người dùng. Tùy thuộc vào đầu vào, tôi sẽ tạo một số Rectangle hoặc Circle, là các lớp con của Object. Nếu không có đầu vào (hoặc không biết), thì tôi sẽ chỉ tạo một đối tượng chung.Làm thế nào để khởi tạo các lớp con khác nhau có điều kiện?

class Object 
{ 
     public: 
      Object(); 
      void Draw(); 
     private: 
      .... 
}; 
class Rectangle:public Object 
{ 
     public: 
      Rectangle(); 
      .... //it might have some additional functions 
     private: 
      .... 
}; 

class Circle:public Object 
{ 
     public: 
      Circle(); 
      .... //it might have some additional functions 
     private: 
      .... 
}; 

Chức năng chính:

string objType; 
getline(cin, objType); 

if (!objType.compare("Rectangle")) 
    Rectangle obj; 
else if (!objType.compare("Circle")) 
    Circle obj; 
else 
    Object obj; 

obj.Draw(); 

Tất nhiên, các mã trên sẽ không làm việc vì tôi không thể tạo một đối tượng bên trong một lệnh If. Vì vậy, tôi đã thử một cái gì đó như thế này.

Object obj; 
if (!objType.compare("Rectangle")) 
    obj = Rectangle(); 
else if (!objType.compare("Circle")) 
    obj = Circle(); 


obj.Draw(); 

Mã này sẽ biên dịch, nhưng nó sẽ không làm những gì tôi muốn. Đối với một số lý do, đối tượng không được khởi tạo theo cách lớp con nên (ví dụ, tôi đặt các biến thành viên của một số đối tượng, cụ thể là một véc tơ, khác nhau trong các lớp con). Tuy nhiên, khi tôi đặt một điểm break tại constructor Child class, nó đã chạy qua đó.

Vậy làm cách nào để đặt đối tượng khởi tạo làm lớp con trong một số câu lệnh if?

Trả lời

10

Bạn có thể tạo đối tượng tự động trong câu hỏi if, nhưng chúng sẽ bị hủy ở cuối phạm vi được tạo để chúng không hoạt động cho vấn đề này.

Lý do bạn không thể thực hiện obj = Rectangle() là vì slicing.

Bạn phải có con trỏ đến Object. Con trỏ đến các đối tượng cơ sở cũng có thể trỏ đến các thể hiện của các đối tượng con. Sau đó, bạn có thể tự động tạo ra các đối tượng bên trong if với new (đối tượng được tạo ra với phạm vi new coi thường và chỉ tiêu diệt khi bạn gọi delete trên một con trỏ cho họ), sau đó delete nó khi bạn đã hoàn tất:

Object* obj = NULL; // obj doesn't point to anything yet 
string objType; 
getline(cin, objType); 

if (objType == "Rectangle") 
    obj = new Rectangle; // make obj point to a dynamic Rectangle 
else if (objType == "Circle") 
    obj = new Circle; // make obj point to a dynamic Circle 
else 
    obj = new Object; // make obj point to a dynamic Object 

obj->Draw(); // draw whatever shape obj really points to 

delete obj; // deallocate dynamic object 

Ngoài ra, bạn có thể sử dụng con trỏ thông minh và sau đó bạn không phải lo lắng về cách deallocating đối tượng theo cách thủ công:

std::unique_ptr<Object> obj(NULL); // obj doesn't point to anything yet 
string objType; 
getline(cin, objType); 

if (objType == "Rectangle") 
    obj.reset(new Rectangle); // make obj point to a dynamic Rectangle 
else if (objType == "Circle") 
    obj.reset(new Circle); // make obj point to a dynamic Circle 
else 
    obj.reset(new Object); // make obj point to a dynamic Object 

obj->Draw(); // draw whatever shape obj really points to 

// the unique_ptr takes care of delete'ing the object for us 
// when it goes out of scope 
+0

Nó hoạt động! Ngoài giải pháp cho vấn đề của tôi, cảm ơn vì đã giải thích tốt về cách thức các lớp và con trỏ hoạt động trong C+++! – tuzzer

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