我在c ++中有一个中期,我们的一个任务是编写一个类,它会重载<<
运算符,以便我们可以将该类的私有字段打印到std::ostream
,如下所示: / p>
Crate c1(2600, 9500);
Crate c2;
cout << c1 << ", " << c2 << endl;
必须打印Crate weight: 2600 Crate value: 9500, Crate weight: 0 Crate value: 0
我的实现是
class Crate {
int weight;
int value;
public:
Crate ():weight(0), value(0) {}
Crate (int w, int v);
Crate& operator+= (Crate& c);
int operator+= (int& w);
friend ostream& operator<< (ostream& out, Crate c) {
out << "Crate weight: " << c.weight;
out << " Crate value: " << c.value;
return out;
}
};
但是,我为重载<<
运算符得到了0/3分,我的解决方案和评估模板之间的唯一区别是我按值传递Crate c
并通过引用传递它。
当然,如果该类将动态分配成员变量,我将不得不通过引用传递它的实例,但这不是这里的情况。
我知道cppreference.com提供的示例使用了一个const引用,但有没有严格的规则,在执行此操作时必须使用const引用?
据我所知,我的解决方案将weight
和value
复制到堆栈而不是只复制指向对象的指针,但是+4字节(如果是32位系统)堆栈确实是一个很大的问题,或者我错过了一些更严重的东西(比如某种类型的内存泄漏)?
我还检查了两种解决方案的反汇编,但我找不到任何可以使我的解决方案值得零点的东西。
我也问过我的教授,但他们开始谈论将其作为const
传递,但我不知道如何使这个解决方案在工作方面更好/不起作用。另一位教授告诉我“这在语法上是完全错误的”。但它是用Visual Studio和MinGW编译的,所以我也不能理解它。
请注意,这是电气工程师的课程。
答案 0 :(得分:5)
在c ++
中通过引用传递类是必须的没有
&#34;将其作为常量传递给#34;这很愚蠢,如果你按价值传递,那么如果你把参数标记为常量,对外界来说并不重要。
要尽可能直接回答您的问题,按值继承其他类并没有错。当物体较小时,最好通过值传递。在您的情况下,在典型的64位平台上,大小差异为0(每个int 2 * 4bytes vs一个8字节指针)。所以你的&#34; +4字节在堆栈上&#34;实际上并不存在,它的大小相同
我预测优化编译器会重写您的代码以使Crate
取值,即使您将其声明为通过引用获取。这将是出于空间局部性和易于访问的原因。如果指针被传递,您需要按照指针来获取数据成员,这会增加一个步骤。
你的教授错误地给你0分,除非在课程中有一些要求非常明确,所有操作员都必须参考参考。 const Crate
与Crate
问题并不重要。
答案 1 :(得分:4)
你不应该收到0,但你也不应该获得全额学分。
friend ostream& operator<< (ostream& out, Crate c)
每次调用它时都会创建一个副本,效率很低。要避免这些副本,您希望通过引用传递,如
friend ostream& operator<< (ostream& out, Crate& c)
但是这引入了一个新问题,即您的第一个版本没有通过引用传递,您需要为该函数提供左值。您将无法像
那样使用它std::cout << Crate();
为了打击我们可以Crate
const &
friend ostream& operator<< (ostream& out, const Crate& c)
,这将避免复制,并允许我们绑定临时工具
{{1}}
答案 2 :(得分:3)
学习通常是关于良好的习惯和一般知识,更不用说你正在写的小例子。
是的,在您的情况下,按性能划分的价值传递不会改变任何事情。但是有两个问题:
至于实际的零作为标记 - 不要在它上面流汗。什么都没有。