2013-11-10 2 views
1

может я знаю, как я использовать перегруженный конструктор для композиции объекта в другом классе, вот пример код:с ++ Использованием перегруженного конструктора по составу объекта

class A { 
    int a; 

    A(int inputA) { a = inputA; } 
}; 

class B { 
    A objectA; 

    B(A inputObjectA) { objectA = inputObjectA; } 
}; 

ошибка с компилятором был не существует конструктор по умолчанию не A :: A()?

Есть ли способ редактировать код в параметре конструктора B, чтобы принять перегруженный конструктор в A?

+0

Используйте список инициализаторов конструктора. – Drop

ответ

2

Если у ребенка нет конструктора по умолчанию, конструктор родителя должен передать параметры.

class A { 
public: 
    int a; 
    A(int inputA) { a = inputA; } 
}; 

class B { 
    A objectA; 
public: 
    B(A inputObjectA): objectA(inputObjectA.a) { } 
}; 

http://ideone.com/QavhfY

В вашем случае было бы целесообразно использовать конструктор копирования для A, вместо того, чтобы его члены общественности:

class A { 
    int a; 
public: 
    A(int inputA) { a = inputA; } 
}; 

class B { 
    A objectA; 
public: 
    B(A inputObjectA): objectA(inputObjectA) { } 
}; 

http://ideone.com/wX1clr

+0

привет, для вашего решения для работы, я ДОЛЖЕН иметь конструктор по умолчанию в классе A правильно ?, так что независимо от того, что мне понадобится конструктор по умолчанию? Если нет, 'B (A inputObjectA): objectA (inputObjectA) {}' приведет к тому, что конструктор по умолчанию не найден – curiosity

+0

В моих решениях нет конструктора по умолчанию для A. И нет, ошибок компилятора не будет. Я добавил ссылки на ideone в качестве доказательства того, что код компилируется в порядке. – Basilevs

+0

спасибо за ваше объяснение, однако моему учебному примеру понадобится B, чтобы принять объект класса A без ссылки. – curiosity

1

В вашем объекте класса B у вас есть

A objectA; 

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

A(int inputA = 0) { a = inputA; } 

Это будет взять на себя роль, что установить это число а 0, при вызове конструктора по умолчанию, это действительно было бы достичь такой же, как

хотя вам не нужно устанавливать a, если вы этого не хотите, но поскольку вы объявили конструктор не по умолчанию, он уже неявно создает его для вас. Таким образом, вы будете нуждаться в минимуме

A(){ } 

Другим способом вы могли бы сделать это

class A { 
    int a; 
    void setSomething(int val) { a = val; } 
}; 

class B { 
    A objectA; 
    B(A inputObjectA) { objectA = inputObjectA; } 
}; 

Это работает, потому что вы никогда не объявляли любой конструктора, поэтому он будет неявно создать по умолчанию один для вас

Наконец, это один из способов, которым вы могли бы это сделать, вероятно, ближе всего к вашему исходному коду, добавив только 3 символа, должны исправить все:

class A { 
    int a; 

    A(int inputA) { a = inputA; } 
}; 

class B { 
    A objectA(0); 

    B(A inputObjectA) { objectA = inputObjectA; } 
}; 
+0

есть ли способ редактировать код в параметре конструктора B, чтобы принять перегруженный конструктор в A. – curiosity

+0

Также, когда вы определяете конструктор для класса, конструктор по умолчанию больше не вызван –

+0

Ошибка не оттуда, это из 'A ObjectA', поэтому эта строка должна изменить –

-1

Вы должны по умолчанию конструктор, потому что у вас есть экземпляр класса A внутри класса B. Если вы немного читаете о порядке, в котором вызываются конструкторы, вы будете notic e, что сначала там называются конструкторы по умолчанию для членов, а затем главный конструктор класса. Итак - в вашем примере - сначала компилятор пытается инициализировать objectA со значением по умолчанию, и он терпит неудачу, потому что нет конструктора по умолчанию.

+0

Существует способ передать аргументы конструкторам nodeefault для таких случаев. B конструктор должен быть изменен для этого. См. мой ответ. – Basilevs

+0

Неправильно. Абсолютной необходимости в конструкторе по умолчанию нет, даже если элемент по значению. – Drop

+0

Хотя то, что вы оба говорите, верно, содержание вопроса было иным, в то время как я предоставлял ответ на него. Пользователь не спрашивал «как изменить бод», но «нужен ли мне конструктор по умолчанию». Поэтому, изменяя код для использования списка инициализаторов, это хорошая идея, ответ на основной вопрос «да, вам это нужно, потому что ...». –

0

Просто передайте параметры A() конструктору B(). Это решение работает для A, который по умолчанию не является конструктивным, не копирует и не перемещает конструктивно/присваиваемый.

class A 
{ 
    int a; 

    // Just to demonstrate non copy-move-ness (can be removed) 
    A() = delete; 
    A(A&) = delete; 
    A(A&&) = delete; 
    A& operator=(A&) = delete; 
    A& operator=(A&&) = delete; 
public: 
    A(int inputA): a(inputA) {} 
}; 

class B 
{ 
    A objectA; 
public: 
    B(int inputA): objectA(inputA) { } 
}; 


int main() 
{ 
    B(42); 
} 

Proof

Совет: не используйте назначение в теле конструктора, используйте конструктор списков инициализации вместо этого.

Вся эта информация вы можете получить от any modern C++ book.

Смежные вопросы