Pertanyaan Bagaimana cara membuat array dengan anggota referensi di C ++?


Saya memiliki beberapa kelas Foo dan Logger:

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

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

Sekarang saya ingin membuat array objek dari class Foo, di mana semua referensi Foo::logger harus menunjukkan hal yang sama Logger obyek. Saya mencoba sesuatu seperti (saya perlu tumpukan dan alokasi tumpukan):

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

Masalahnya adalah bahwa kedua versi mencoba memanggil konstruktor default Foo() yang tidak hadir. Juga, sebagaimana yang saya pahami, tidak mungkin mengubah variabel referensi yang direferensikan. Jadi panggilan sementara ke konstruktor default dan inisialisasi kemudian dalam satu lingkaran juga tidak membantu.

Jadi: Apa cara yang tepat untuk melakukannya? Apakah saya perlu menggunakan pointer ke Logger obyek?


5
2018-04-04 13:38


asal


Jawaban:


Untuk penggunaan umum saya biasanya membuat logger a Singleton sehingga hanya ada satu dan dapat diakses dari semua komponen. http://en.wikipedia.org/wiki/Singleton_pattern

Ini juga membuat konstruktor Foo jauh lebih sederhana.

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

Dan gunakan di Foo seperti:

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

atau

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

(Penghargaan untuk singleton dari @Loki Astari: Pola desain C ++ Singleton )


2
2018-04-04 13:59



Anda tidak dapat menginisialisasi array objek dengan konstruktor non-default. Namun Anda dapat menggunakan vektor seperti yang ditunjukkan sini (Lihatlah jawaban pertama)

Dan untuk heap Anda dapat melakukan hal-hal berikut:

Foo* pObjects[3];

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

5
2018-04-04 13:47



Anda dapat menginisialisasi array objec dengan konstruktor non-default menggunakan inisialisasi brace C ++ 11:

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

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


EDIT: Di C ++ 11, Anda dapat menggunakan vector untuk melakukan apa yang Anda inginkan:

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

Perhatikan bahwa vector solusi tidak akan berfungsi di C ++ 03. Di C + + 03 yang dibangkitkan oleh konstruktor vektor Foo::operator=. Dalam C ++ 11, perintah ini diaktifkan Foo::Foo(const Foo&).


2
2018-04-04 13:55