【问题标题】:Properly instantiating an object in C++ [duplicate]在 C++ 中正确实例化对象 [重复]
【发布时间】:2016-03-24 12:59:55
【问题描述】:

我有一段时间使用 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++ 技能,您可能会很快发现错误。我只是想了解我做错了什么以及为什么。 提前感谢您的关注。

【问题讨论】:

  • 这个问题其实和模板无关,但是每当你写T t();这不会创建一个T类型的对象,叫做t。相反,它声明了一个带零参数的函数,返回 T
  • 现在的简单解决方案是T t{};(大括号),不能将其误认为是函数声明。
  • 我看到了混乱......非常感谢您的快速回复!也是为了让我知道这是一个骗局。我真的没有找到任何接近我想要的东西,我猜可能是使用了错误的搜索词......

标签: c++


【解决方案1】:

如果你启用编译警告,你会得到:

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的原因。

【讨论】:

  • 我明白了。从现在开始记得使用警告标志进行编译!感谢您的快速回复...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-01
  • 2012-08-20
  • 1970-01-01
  • 2020-12-27
  • 1970-01-01
相关资源
最近更新 更多