2010-05-18 40 views

Trả lời

23

Bạn có thể trả về một con trỏ lớp trừu tượng - giả B là một lớp bê tông có nguồn gốc từ lớp trừu tượng A:

A * f() { 
    return new B; 
} 

hoặc một tài liệu tham khảo:

A & f() { 
    static B b; 
    return b; 
} 

hoặc một con trỏ thông minh:

std::unique_ptr<A> f() { 
    return std::make_unique<B>(...); 
} 
+0

tôi muốn sử dụng lớp trừu tượng (hoặc tham chiếu của nó), để sử dụng nó như một dạng chung cho các lớp khác có nguồn gốc từ lớp trừu tượng – cemregoksu

+0

@cemregoksu Đó là mục đích duy nhất để có một bản tóm tắt lớp học. Cả hai hàm trên minh họa cách bạn thực hiện việc này đối với các giá trị trả về hàm. –

+0

cảm ơn sự giúp đỡ của bạn. tôi nghĩ rằng nó hoạt động =) – cemregoksu

3

Lớp trừu tượng không thể được khởi tạo và do đó không được trả lại.

+0

Còn tham chiếu thì sao? Tôi biết rằng không thể chuyển lớp trừu tượng thành tham số cho hàm, nhưng tôi có thể chuyển tham chiếu của lớp trừu tượng. – cemregoksu

+0

Chỉ khi tham chiếu thực sự đề cập đến một thể hiện của một lớp con. –

+0

tốt, còn kịch bản đó thì sao? lớp A { khoảng trống ảo f() = 0; }; void fonk (A & a) {} hoạt động. vì vậy có thể tạo thành hàm để trả về tham chiếu của lớp không? – cemregoksu

4

Không, nhưng hàm có thể có kiểu trả về của con trỏ (hoặc tham chiếu) cho lớp trừu tượng. Sau đó nó sẽ trả về các cá thể của một lớp có nguồn gốc từ lớp trừu tượng.

+0

Bạn có nghĩa là "kiểu trả về * tham chiếu đến * một lớp trừu tượng". – avakar

+0

Tôi không thể hiểu ý bạn là gì. bạn có thể đưa ra một ví dụ nhỏ không? – cemregoksu

+1

@incrediman: sau đó anh ấy sai. – avakar

16

Bạn có thể khai báo loại trả về là tham chiếu hoặc con trỏ đến lớp trừu tượng, để nó có thể được gán cho tham chiếu hoặc con trỏ tới lớp trừu tượng và được sử dụng dựa trên giao diện của nó.

Tuy nhiên, bạn không thể trả lại phiên bản thực tế của lớp trừu tượng thực tế vì theo định nghĩa, bạn không thể khởi tạo nó. Tuy nhiên, bạn có thể trả về các thể hiện của các kiểu con cụ thể là đủ tốt vì bởi principle of substitution, bạn nên luôn có thể sử dụng một kiểu con thay vì một siêu kiểu.

1

Nhà máy mẫu thiết kế là một ví dụ về việc trả lại một con trỏ đến một đối tượng lớp trừu tượng:

class Base 
{ ; } 

class One : public Base 
{ ; } 

class Two : public Base 
{ ; } 

Base * Factory(unsigned int number) 
{ 
    Base * p_item(NULL); 
    switch (number) 
    { 
    case 1: 
     p_item = new One; 
     break; 
    case 2: 
     p_item = new Two; 
     break; 
    default: 
     p_item = NULL; 
     break; 
    } 
    return p_item; 
} 

Một đối tượng lớp cơ sở trừu tượng thực tế không bao giờ có thể được trả lại vì không bao giờ có thể là một dụ của một lớp cơ sở trừu tượng. Các con trỏ và tham chiếu đến một kiểu cơ sở trừu tượng có thể được trả về như trong ví dụ trên.

Con trỏ và tham chiếu đến lớp cơ sở trừu tượng được trả về từ hàm hoặc phương thức thực sự tham chiếu đến hậu duệ của loại cơ sở trừu tượng.

-3

Tôi biết mình hơi muộn nhưng tôi hy vọng điều này sẽ giúp ai đó ...

Là một newbie trong C++ lập trình, tôi cũng bị mắc kẹt trong một thời gian về vấn đề đó. Tôi muốn tạo một phương thức factory trả về một tham chiếu đến một đối tượng trừu tượng. Giải pháp đầu tiên của tôi bằng cách sử dụng con trỏ làm việc tốt nhưng tôi muốn ở lại trong một "C + + cách" hơn. Đây là đoạn mã tôi đã viết để chứng minh điều đó:

#include <iostream> 

using std::cout; 
using std::endl; 

class Abstract{ 
public: 
    virtual void foo() = 0; 
}; 

class FirstFoo: public Abstract{ 
    void foo() 
    { 
    cout << "Let's go to the foo bar!" << endl; 
    } 
}; 

class SecondFoo: public Abstract{ 
    void foo() 
    { 
    cout << "I prefer the foo beer !" << endl; 
    } 
}; 

Abstract& factoryMethod(){ 
    static int what = 0; 

    if(what++ % 2 == 0) 
    return *(new FirstFoo()); 
    else 
    return *(new SecondFoo()); 
} 

int main(int argc, char* argv[]) 
{ 
    int howMany = 10; 
    int i = 0; 

    while(i++ < howMany) 
    { 
    Abstract& abs = factoryMethod(); 
    abs.foo(); 
    delete &abs; 
    } 
} 

Mở với mọi phê bình!

+3

'factoryMethod' rò rỉ bộ nhớ mỗi khi bạn gọi nó. Kết quả được phân bổ trên heap, nhưng nó không bao giờ bị xóa. (Người gọi không thể xóa nó vì họ nhận được một tham chiếu thay vì một con trỏ.) –

+0

Trong C++ 11, std :: unique_ptr hoạt động. – user877329

+0

Tôi đồng ý với vấn đề rò rỉ bộ nhớ, nhưng tôi vừa học được cách nhập các ký hiệu cụ thể từ một không gian tên bằng cách sử dụng 'using', tôi chỉ biết về' using namespace' cho đến nay! Cảm ơn vì @morandg! – stakx

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