Как инициализировать данные члена класса с другими данными члена этого класса? - PullRequest
0 голосов
/ 29 октября 2011

У меня есть класс A и B. B является членом A. Мне нужно инициализировать B с другими элементами данных A.

class A;
class B
{
 public:
    B(A& a){cout << "B constr is run \n";}
};

class A
{
 public:
    A(){}

    void initB(A& a){b(a); cout << "A call init B \n"; }
 private:
    // other members ...

    B b;
};

int main()
{
    A a;
    a.initB(a);

}

Я получил ошибку компиляции:

classIns.cpp: In constructor âA::A()â:
classIns.cpp:14: error: no matching function for call to âB::B()â
classIns.cpp:8: note: candidates are: B::B(A&)
classIns.cpp:6: note:                 B::B(const B&)
classIns.cpp: In member function âvoid A::initB(A&)â:
classIns.cpp:16: error: no match for call to â(B) (A&)â

Почему A () {} должен вызывать B :: B ()?

Как инициализировать B с другими элементами данных A?

спасибо

Ответы [ 4 ]

4 голосов
/ 29 октября 2011

B не имеет конструктора по умолчанию, что означает, что у вас есть для инициализации его в ctor A.

struct A {
    A() : b(*this) {}
private:
    B b;
};

Каждый раз, когда вы думаете об использовании initКак и члены, вы, вероятно, делаете это неправильно.Объект всегда должен быть действительным после завершения конструктора.

1 голос
/ 29 октября 2011

Вы можете использовать цепочку инициализации в конструкторе A:

class B
{
    public:
        B(Type1 x, Type2 y)
        {

        }
        void init(Type1 x, Type2 y) { ........} 
};
class A
{
    public:
        A() : Amember1(), Amember2(), b(Amember1, Amember2) {}
    private:
        Type1 Amember1;
        .....
        B b;
};

Но вы не можете вызвать конструктор B внутри initB метода, потому что b уже создан.Вы можете использовать метод B::init() с данными A, например:

void A::initB(A& a){ b.init(a.Amember1, a.Amember2); cout << "A call init B \n"; }
1 голос
/ 29 октября 2011

Вот так:

void initB(A& a){
  b = B(a); 
  cout << "A call init B \n"; 
}

Конечно, класс B нуждается в конструкторе по умолчанию и конструкторе копирования, который принимает ссылку на объект типа A.

0 голосов
/ 29 октября 2011

Почему A () {} должен вызывать B :: B ()?

Поскольку A имеет элемент данных B, который необходимо инициализировать при создании экземпляраКласс.В вашем случае b инициализируется с B c'tor по умолчанию.

Поскольку вы указываете конструктор для B

public:
    B(A& a){cout << "B constr is run \n";}

Конструктор по умолчанию:

    B(){}

не генерируется автоматически компилятором.Так что жалуется.

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