2012-04-04 40 views
5

Tôi có một số lớp Foo và Logger:Làm thế nào để tạo một mảng với thành viên tham chiếu trong C++?

class Logger{/* something goes here */}; 
class Foo{ 
    Foo(Logger& logger); 
    Logger& logger; 
} 

Foo::Foo(Logger& logger) : logger(logger) 
{} 

Bây giờ tôi muốn tạo một mảng các đối tượng của lớp Foo, nơi tất cả các tài liệu tham khảo Foo::logger phải trỏ đến cùng một đối tượng Logger. Tôi cố gắng một cái gì đó tương tự (Tôi cần cả hai ngăn xếp và phân bổ đống):

Logger log (/* parameters */); 
Foo objects [3] (log); // On stack 
Foo* pObjects = new Foo [3] (log); // On heap 

Vấn đề là cả hai phiên bản thử để gọi constructor mặc định Foo() mà không phải là hiện tại. Ngoài ra, tôi hiểu rằng không thể thay đổi biến được tham chiếu của tham chiếu. Vì vậy, một cuộc gọi tạm thời đến constructor mặc định và sau đó initalisation trong một vòng lặp cũng không giúp đỡ.

Vì vậy: Cách phù hợp để làm điều đó là gì? Tôi có cần sử dụng con trỏ đến đối tượng Logger không?

Trả lời

2

Để sử dụng chung, tôi thường tạo một trình ghi nhật ký một Singleton để chỉ có một và có thể truy cập được từ tất cả các thành phần. http://en.wikipedia.org/wiki/Singleton_pattern

Điều này cũng làm cho hàm tạo của Foo đơn giản hơn nhiều.

class Logger 
{ 
    public: 
     static Logger& getInstance() 
     { 
      static Logger instance; 
      return instance; 
     } 

     public log(const std::string& txt) 
     { 
      //do something 
     } 

    private: 
     Logger() {} 
     Logger(Logger const&);    // Don't Implement. 
     void operator=(Logger const&); // Don't implement 
}; 

Và sử dụng nó trong Foo như:

Logger::getInstance().log("test"); 

hoặc

Logger& logger = Logger::getInstance(); 
logger.log("test"); 

(Cho vay để singleton từ @Loki ASTARI: C++ Singleton design pattern)

+0

Để chắc chắn rằng tôi hiểu bạn: Bạn có nghĩa là một số thành viên tĩnh cho tất cả các đối tượng? Làm thế nào để khởi tạo nó sau đó? Hoặc một đối tượng riêng biệt/biến toàn cục/...? –

+0

Anh ấy có nghĩa là một lớp singleton có thể truy cập từ mọi nơi trong mã của bạn. Đây là cách phổ biến cho logger. – giorashc

5

Bạn không thể khởi tạo một mảng đối tượng có hàm tạo không mặc định. Tuy nhiên bạn có thể sử dụng một vector như here (Nhìn vào câu trả lời đầu tiên)

Và đối với những đống bạn có thể làm như sau:

Foo* pObjects[3]; 

for (int i = 0; i < 3; ++i) { 
    pObjects[i] = new Foo(log); 
} 
2

Bạn có thể khởi tạo một mảng của objecs với không mặc định nhà xây dựng bằng cách sử dụng C++ 11 cú đúp khởi:

class Logger{/* something goes here */}; 
class Foo{ 
public: 
    Foo(Logger& logger); 
private: 
    Logger& logger; 
}; 

Foo::Foo(Logger& logger) : logger(logger) 
{} 


EDIT: Trong C++ 11, bạn có thể sử dụng vector để làm những gì bạn muốn:

#include <vector> 
class Logger{/* something goes here */}; 
class Foo{ 
public: 
    Foo(Logger& logger) : logger(logger) {} 
private: 
    Logger& logger; 
}; 

int main() { 
    Logger log; 
    std::vector<Foo>(3, log); 
} 

Lưu ý rằng giải pháp vector sẽ không hoạt động trong C++ 03. Trong C++ 03 rằng hàm tạo vector gọi Foo::operator=. Trong C++ 11 nó gọi Foo::Foo(const Foo&).

+0

Đó chỉ hoạt động nếu tôi biết số yếu tố ưu tiên, phải không? Điều này không phải lúc nào cũng đúng cho vấn đề của tôi. –

+0

Đúng, đó là một vấn đề. Nhưng nhận ra rằng bạn phải biết số lượng phần tử * ưu tiên * khi bạn tạo mảng trên ngăn xếp. –

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