Здравей Гергана,
Грешката се получава, защото при създаването на обект от клас А преди да се изпълни тялото на конструктора на А се извиква конструктира по подразбиране на myB. Тъй като такъв няма, защото си дефинирала собствен конструктор с параметри, се получава грешка при компилиране. Mожеш изрично да извикаш конструктура с параметри ето така.
A(T _a, T _b):myB(_a, _b) { }
При извикването на конструктор, преди да се изпълни кода в тялото му, се извикват всички конструктори по подразбиране на член-данните, ако има такива, и конструктурите по подразбиране на родителските класове, ако класът участва в йерархия на наследяване. Това се случва ако не сме извикали изрично конструктурите. Ако сме извикали изрично някой конкретен конструктор извикването на този по подразбиране ще се прескочи.
struct A {
private:
struct B {
int data;
B() {
data = 42;
}
B(int data) {
this->data = data;
}
};
B b1;
B b2;
public:
A():b2(20) {
b1.data = 50;
}
};
В този пример, при конструирането на обект от тип А, за b1 ще се извика конструктора по подразбиране, а за b2 ще се извика конструктура с параметри. След това ще влезем в тялото на конструктура на А и стойността на b1.data ще се промени на 50.
One more thing...
Забелязах, че в B myB подаваш T като аргумент на шаблона. Това би било вярно, ако B не е вложена в А, но тук това е грешка и не би трябвало да се компилира. Структурата B е декларирана в класа А и "вижда" типа Т. Типът Т се знае от аргумента на шаблона на А. А, A и т. н. Пълното изписване на типа на B е А<Т>::B и оттук се вижда, че структурата В не е шаблонна, само класа А е.
Разбира се, нищо не пречи да я направим и нея шаблонна.
template<typename T>
Грешката се получава, защото при създаването на обект от клас А преди да се изпълни тялото на конструктора на А се извиква конструктира по подразбиране на myB. Тъй като такъв няма, защото си дефинирала собствен конструктор с параметри, се получава грешка при компилиране. Mожеш изрично да извикаш конструктура с параметри ето така.
A(T _a, T _b):myB(_a, _b) { }
При извикването на конструктор, преди да се изпълни кода в тялото му, се извикват всички конструктори по подразбиране на член-данните, ако има такива, и конструктурите по подразбиране на родителските класове, ако класът участва в йерархия на наследяване. Това се случва ако не сме извикали изрично конструктурите. Ако сме извикали изрично някой конкретен конструктор извикването на този по подразбиране ще се прескочи.
struct A {
private:
struct B {
int data;
B() {
data = 42;
}
B(int data) {
this->data = data;
}
};
B b1;
B b2;
public:
A():b2(20) {
b1.data = 50;
}
};
В този пример, при конструирането на обект от тип А, за b1 ще се извика конструктора по подразбиране, а за b2 ще се извика конструктура с параметри. След това ще влезем в тялото на конструктура на А и стойността на b1.data ще се промени на 50.
One more thing...
Забелязах, че в B myB подаваш T като аргумент на шаблона. Това би било вярно, ако B не е вложена в А, но тук това е грешка и не би трябвало да се компилира. Структурата B е декларирана в класа А и "вижда" типа Т. Типът Т се знае от аргумента на шаблона на А. А, A и т. н. Пълното изписване на типа на B е А<Т>::B и оттук се вижда, че структурата В не е шаблонна, само класа А е.
Разбира се, нищо не пречи да я направим и нея шаблонна.
template<typename T>
class A {
template<typename U>
template<typename U>
struct B {
U a;
U b;
B(U _a, U _b) {
a = _a;
b = _b;
}
};
B<T> myB;
B<int> b_int;
B<double> b_double;
public:
A(T _a, T _b):myB(_a, _b), b_int(1, 2), b_double(3.14, 2.71) { }
};
И дори нищо не ни пречи да сложим член-данна от тип Т в B.
template<typename T>
U a;
U b;
B(U _a, U _b) {
a = _a;
b = _b;
}
};
B<T> myB;
B<int> b_int;
B<double> b_double;
public:
A(T _a, T _b):myB(_a, _b), b_int(1, 2), b_double(3.14, 2.71) { }
};
И дори нищо не ни пречи да сложим член-данна от тип Т в B.
template<typename T>
class A {
template<typename U>
template<typename U>
struct B {
T a;
U b;
B(T _a, U _b) {
a = _a;
b = _b;
}
};
B<double> myB;
public:
A(T _a, double _b): myB(_a, _b) { }
};
int main() {
A<int> obj(42, 3.14);
}
Сега obj.myB.a e int, а obj.myB.b е double.
Поздрави,
Дамян
T a;
U b;
B(T _a, U _b) {
a = _a;
b = _b;
}
};
B<double> myB;
public:
A(T _a, double _b): myB(_a, _b) { }
};
int main() {
A<int> obj(42, 3.14);
}
Сега obj.myB.a e int, а obj.myB.b е double.
Поздрави,
Дамян