Курсови проекти

Получена грешка

Re: Получена грешка

by Дамян Бойчев -
Number of replies: 0
Здравей Гергана,

Грешката се получава, защото при създаването на обект от клас А преди да се изпълни тялото на конструктора на А се извиква конструктира по подразбиране на 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>
    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>
class A {
    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.

Поздрави,
Дамян