在C ++中正确实例化对象

时间:2016-03-24 12:59:56

标签: c++

我有一段时间使用C的经验,一般少时间使用OOP,但现在才开始尝试学习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被正确实例化,但mat2表现得很苛刻。据推测,这是一个微不足道的问题,但我只是非常努力。产生的产量如下:

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。为什么呢?

我是否正确地实例化了对象?在自动内存中初始化对象的正确方法是什么?我知道这对基于范围的资源管理很重要......

我具有初级C ++技能,你可能会很快发现错误。我只想了解我做错了什么以及为什么。 提前感谢您的关注。

1 个答案:

答案 0 :(得分: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时,除了application: acuteservice-1260 version: 1 runtime: php55 api_version: 1 threadsafe: yes handlers: - url: /(.*\.(gif|png|jpg|ico|js|css|eot|svg|ttf|woff)) static_files: \1 upload: (.*\.(gif|png|jpg|ico|js|css|eot|svg|ttf|woff)) - url: /favicon\.ico static_files: favicon.ico upload: favicon\.ico - url: .* script: index.php 之外,这几乎解释了所有内容。