Могу ли я вызвать конструктор из другого конструктора (сделать цепочку конструктора) в C ++? - PullRequest
840 голосов
/ 21 ноября 2008

Как разработчик C # , я привык бегать через конструкторы:

class Test {
    public Test() {
        DoSomething();
    }

    public Test(int count) : this() {
        DoSomethingWithCount(count);
    }

    public Test(int count, string name) : this(count) {
        DoSomethingWithName(name);
    }
}

Есть ли способ сделать это в C ++?

Я пытался назвать имя класса и использовать ключевое слово this, но оба не удаются.

Ответы [ 15 ]

2 голосов
/ 11 ноября 2015

Этот подход может работать для некоторых типов классов (когда оператор присваивания работает "хорошо"):

Foo::Foo()
{
    // do what every Foo is needing
    ...
}

Foo::Foo(char x)
{
    *this = Foo();

    // do the special things for a Foo with char
    ...
}
2 голосов
/ 02 ноября 2014

Я бы предложил использовать метод private friend, который реализует прикладную логику конструктора и вызывается различными конструкторами. Вот пример:

Предположим, у нас есть класс с именем StreamArrayReader с некоторыми закрытыми полями:

private:
    istream * in;
      // More private fields

И мы хотим определить два конструктора:

public:
    StreamArrayReader(istream * in_stream);
    StreamArrayReader(char * filepath);
    // More constructors...

Там, где второй просто использует первый (и, конечно, мы не хотим дублировать реализацию первого). В идеале хотелось бы сделать что-то вроде:

StreamArrayReader::StreamArrayReader(istream * in_stream){
    // Implementation
}

StreamArrayReader::StreamArrayReader(char * filepath) {
    ifstream instream;
    instream.open(filepath);
    StreamArrayReader(&instream);
    instream.close();
}

Однако это не разрешено в C ++. По этой причине мы можем определить метод приватного друга следующим образом, который реализует то, что должен делать первый конструктор:

private:
  friend void init_stream_array_reader(StreamArrayReader *o, istream * is);

Теперь этот метод (потому что он друг) имеет доступ к закрытым полям o. Затем первый конструктор становится:

StreamArrayReader::StreamArrayReader(istream * is) {
    init_stream_array_reader(this, is);
}

Обратите внимание, что это не создает несколько копий для вновь созданных копий. Второй становится:

StreamArrayReader::StreamArrayReader(char * filepath) {
    ifstream instream;
    instream.open(filepath);
    init_stream_array_reader(this, &instream);
    instream.close();
}

То есть вместо того, чтобы один конструктор вызывал другой, оба вызывают частного друга!

1 голос
/ 06 января 2014

При вызове конструктора он фактически выделяет память либо из стека, либо из кучи. Таким образом, вызов конструктора в другом конструкторе создает локальную копию. Таким образом, мы модифицируем другой объект, а не тот, на котором мы сосредоточены.

1 голос
/ 21 ноября 2008

Если я правильно понимаю ваш вопрос, вы спрашиваете, можете ли вы вызвать несколько конструкторов в C ++?

Если это то, что вы ищете, то нет - это невозможно.

Вы, конечно, можете иметь несколько конструкторов, каждый с уникальными сигнатурами аргументов, а затем вызывать тот, который вам нужен, когда вы создаете новый объект.

Вы можете даже иметь один конструктор с аргументами по умолчанию на конце.

Но у вас может не быть нескольких конструкторов, а затем вызывать каждый из них по отдельности.

0 голосов
/ 09 сентября 2016

Было бы проще проверить, чем решить :) Попробуйте это:

#include <iostream>

class A {
public:
    A( int a) : m_a(a) {
        std::cout << "A::Ctor" << std::endl;    
    }
    ~A() {
        std::cout << "A::dtor" << std::endl;    
    }
public:
    int m_a;
};

class B : public A {
public:
    B( int a, int b) : m_b(b), A(a) {}
public:
    int m_b;
};

int main() {
    B b(9, 6);
    std::cout << "Test constructor delegation a = " << b.m_a << "; b = " << b.m_b << std::endl;    
    return 0;
}

и скомпилируйте его с 98 std: g ++ main.cpp -std = c ++ 98 -o test_1

вы увидите:

A::Ctor
Test constructor delegation a = 9; b = 6
A::dtor

так:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...