2016-03-24 5 views
1

У меня есть некоторое время опыта с C, некоторые меньше время с ООП вообще, но только сейчас они пытаются изучить C++. Это упражнение по шаблонам.Правильное создание объекта в C++

У меня есть простой класс:

struct type { 

    type(double data = 0) : data(data) 
    { 
     std::cout << "at type constructor" << std::endl; 
    } 

    friend std::ostream& operator<<(std::ostream& out, const type &that) 
    { 
     return out << "[" << std::setfill('0') << std::setw(7) << 
      std::fixed << std::setprecision(2) << that.data << "]"; 
    } 

    private: 
     double data; 
}; 

И основной шаблон:

template<typename T> 
struct mat4 { 

    T a1, a2, a3, a4; 
    T b1, b2, b3, b4; 
    T c1, c2, c3, c4; 
    T d1, d2, d3, d4; 

    mat4 (T a1 = T(), T a2 = T(), T a3 = T(), T a4 = T(), 
      T b1 = T(), T b2 = T(), T b3 = T(), T b4 = T(), 
      T c1 = T(), T c2 = T(), T c3 = T(), T c4 = T(), 
      T d1 = T(), T d2 = T(), T d3 = T(), T d4 = T()) : 
     a1(a1), b1(a2), c1(a3), d1(a4), 
     a2(b1), b2(b2), c2(b3), d2(b4), 
     a3(c1), b3(c2), c3(c3), d3(c4), 
     a4(d1), b4(d2), c4(d3), d4(d4) 
    { 
     std::cout << "at mat4 consctructor" << std::endl; 
    } 

    friend std::ostream& operator<<(std::ostream& out, const mat4 &that) 
    { 
     return out << that.a1 << that.a2 << that.a3 << that.a4 << std::endl << 
        that.b1 << that.b2 << that.b3 << that.b4 << std::endl << 
        that.c1 << that.c2 << that.c3 << that.c4 << std::endl << 
        that.d1 << that.d2 << that.d3 << that.d4; 
    } 
}; 

С основной программе:

int main(int argc, char *argv[]) 
{ 
    mat4<type> mat1(1, 0, 0, 0, 
        0, 1, 0, 0, 
        0, 0, 1, 0, 
        0, 0, 0, 1); 

    std::cout << mat1 << std::endl; 

    mat4<type> mat2(); 

    std::cout << mat2 << std::endl; 

    mat4<type> mat3; 

    std::cout << mat3 << std::endl; 

    return 0; 
} 

Теперь MAT1 и mat3 инстанцируются правильно, но мат2 ведет себя странно. По-видимому, это тривиальная проблема, но я просто сильно не справляюсь. Ouput производится следующим образом:

at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at mat4 consctructor 
[0001.00][0000.00][0000.00][0000.00] 
[0000.00][0001.00][0000.00][0000.00] 
[0000.00][0000.00][0001.00][0000.00] 
[0000.00][0000.00][0000.00][0001.00] 
1 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at type constructor 
at mat4 consctructor 
[0000.00][0000.00][0000.00][0000.00] 
[0000.00][0000.00][0000.00][0000.00] 
[0000.00][0000.00][0000.00][0000.00] 
[0000.00][0000.00][0000.00][0000.00] 

Как вы видите, MAT1 и mat3 выход хорошо, в то время как выход MAT2 является 1. Зачем?

Я правильно создаю объект? Каков правильный способ инициализации объекта в автоматической памяти? Я понимаю, что это важно для управления ресурсами на основе ...

У меня начальный уровень навыков на С ++, и вы, вероятно, заметите ошибку очень быстро. Я просто хотел бы понять, что я делаю неправильно и почему. Заранее благодарим за внимание.

+4

проблема на самом деле не связана с шаблонами, но всякий раз, когда вы пишете 'T t();' это не создаст объект типа 'T', называемый' t'. Вместо этого он объявляет функцию с нулевыми параметрами, возвращающими 'T' – user463035818

+1

. Простым решением является теперь' T t {}; '(фигурные скобки), которые нельзя ошибочно принять за объявление функции. – MSalters

+0

Я вижу путаницу ... Большое вам спасибо за быстрый ответ! Также для того, чтобы сообщить мне, что это был обман. Я действительно не нашел ничего близкого к тому, что я хотел, вероятно, использовал плохие условия поиска, я думаю ... – DVNO

ответ

5

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

main.cpp:59:20: warning: empty parentheses interpreted as a function declaration [-Wvexing-parse] 
    mat4<type> mat2(); 
        ^~ 
main.cpp:59:20: note: remove parentheses to declare a variable 
    mat4<type> mat2(); 
        ^~ 
main.cpp:61:18: warning: address of function 'mat2' will always evaluate to 'true' [-Wpointer-bool-conversion] 
    std::cout << mat2 << std::endl; 
       ~~ ^~~~ 

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

+0

Я понимаю. Не забудьте скомпилировать с помощью предупреждающих флагов! Спасибо за быстрый ответ... – DVNO

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