У меня есть два класса A
и B
. bclass
типа B
является постоянным членом класса A
; то, что я хочу сделать, это инициализировать класс bclass
со значениями по умолчанию, если объект B
не указан A
. Что-то вроде этого:Инициализировать член класса const со значением по умолчанию
#include <iostream>
#include <string>
#include <unistd.h>
using namespace std;
class B{
public:
B(string Bs): Bstring(Bs){
cout << "B constructor: " << Bstring << endl;
}
~B(){
cout << "B destructor: " << Bstring << endl;
}
private:
const string Bstring;
};
class A{
public:
A(const B subb = B("mmmmm")): bclass(subb){
cout << "A constructor." << endl;
}
~A(){
cout << "A destructor." << endl;
}
private:
const B bclass;
};
int main(void){
A a;
cout << "doing work..." << endl;
sleep(2);
return 0;
}
Выход:
B constructor: mmmmm
A constructor.
B destructor: mmmmm
doing work...
A destructor.
B destructor: mmmmm
Дело в том, что я строить 2 B классы, когда только один нужен (?)! И как-то, конструктор B вызывается только один раз, а деструктор называется дважды ... Что происходит ?!
EDIT 1:
После прочтения (большой) ответ @WhiZTiM, я добавил следующие два обновления ...
Следующий код объясняет, когда второй конструктор вызывается:
#include <iostream>
#include <string>
#include <unistd.h>
using namespace std;
class B{
public:
B(string Bs): Bstring(Bs){
cout << "B constructor: " << Bstring << endl;
}
B(const B& bobj): Bstring(bobj.Bstring + "(copy)"){
cout << "B copy constructor: " << Bstring << endl;
}
~B(){
cout << "B destructor: " << Bstring << endl;
}
private:
const string Bstring;
};
class A{
public:
A(const B& subb = B("mmmmm")): bobj(subb){
cout << "A constructor." << endl;
}
~A(){
cout << "A destructor." << endl;
}
private:
const B bobj;
};
int main(void){
A a;
cout << "doing work..." << endl;
sleep(2);
return 0;
}
выход:
B constructor: mmmmm
B copy constructor: mmmmm(copy)
A constructor.
B destructor: mmmmm
doing work...
A destructor.
B destructor: mmmmm(copy)
Как @WhiZTiM указал на меня, компилятор подал третий вызов конструктору B (спасибо!).
EDIT 2: Как я хочу только 1 объект B, лучше всего использовать указатели. Код должен быть:
#include <iostream>
#include <string>
#include <unistd.h>
using namespace std;
class B{
public:
B(const string Bs): Bstring(Bs){
cout << "B constructor: " << Bstring << endl;
}
B(const B& bobj): Bstring(bobj.Bstring){
cout << "copying an existing B object." << endl;
}
~B(){
cout << "B destructor: " << Bstring << endl;
}
private:
const string Bstring;
};
class A{
public:
A(B* subb = new B("mmmmm")): objb(subb){
cout << "A constructor." << endl;
}
~A(){
cout << "A destructor." << endl;
delete objb;
}
private:
const B* const objb;
};
int main(void){
A a1; // This will call the default B constructor.
A a2(new B("ooooo"));// This is calling a non default B object constructor.
cout << "doing work..." << endl;
sleep(2); //I need more motivation...
return 0;
}
Это выход: (?)
B constructor: mmmmm
A constructor.
B constructor: ooooo
A constructor.
doing work...
A destructor.
B destructor: ooooo
A destructor.
B destructor: mmmmm
Большое спасибо @WhiZTiM
'B' не является постоянным подклассом. 'A' является составным объектом' B' – WhiZTiM
Предпочитают 'A (const B & subb = B (" mmmmm "))'. 'A (const B subb = B (...))' довольно неплохая идея, потому что вы не можете «переместить» объект 'const' ... Или еще лучше [pass-by-value] (http: // stackoverflow .com/questions/7592630/is-pass-by-value-a-rational-default-in-c11) 'A (B subb = B (" mmmmm "))' – WhiZTiM