在 C++ 中是否必须通过引用传递 类
Is it obligatory to pass classes by reference in c++
我有一个 C++ 期中考试,我们的作业之一是编写一个 class,它重载了 <<
运算符,以便我们可以将 class 的私有字段打印到std::ostream
,像这样:
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
而他们传递它参考。
当然,如果 class 有动态分配的成员变量,我将不得不通过引用传递它的实例,但这里不是这种情况。
我知道 cppreference.com 中提供的示例使用了 const 引用,但是是否有任何严格的规则要求在执行此操作时必须使用 const 引用?
我知道我的解决方案将 weight
和 value
都复制到堆栈而不是只复制指向对象的指针,但是是 +4 字节(在 32 位系统的情况下)堆栈上真的有那么多问题,还是我遗漏了更严重的东西(比如某种内存泄漏)?
我也检查了这两个解决方案的反汇编,但我找不到任何能让我的解决方案值零分的东西。
我也问过我的教授,但他们开始谈论将其作为 const
传递,但我看不出这将如何使这个解决方案在工作/不工作方面变得更好。另一位教授告诉我 "this is syntactically completely incorrect." 但是它是用 Visual Studio 和 MinGW 编译的,所以我也无法理解。
另请注意,这是一门面向电气工程师的课程。
在c++中是否必须通过引用传递classes
没有
"Passing it as const" 太傻了,如果你按值传递,那么你将参数标记为 const 对外界来说并不重要。
尽量直接回答你的问题,按值取另一个class没有错。当对象较小时,最好按值传递。在您的情况下,典型 64 位平台上的大小差异为 0(每个 int 2 * 4 字节与一个 8 字节指针)。所以你的“+4 bytes on the stack”其实是不存在的,大小一样
我预测优化编译器会重写您的代码以按值获取 Crate
,即使您将其声明为按引用获取。这将是出于空间局部性原因和易于访问。如果传递的是指针,则需要跟随指针到达数据成员,这会增加一个步骤。
你的教授给你0分是错误的,除非课程中有明确要求所有运算符都必须带参考参数。 const Crate
与 Crate
的问题无关紧要。
你不应该得到 0 分,但你也不应该得到满分。
friend ostream& operator<< (ostream& out, Crate c)
每次调用时都会创建一个副本,这可能效率低下。为了避免那些你想通过引用传递的副本,比如
friend ostream& operator<< (ostream& out, Crate& c)
但这引入了一个新问题,您的第一个版本没有通过引用传递您需要为函数提供左值。你将无法像
那样使用它
std::cout << Crate();
为了解决这个问题,我们可以采用 const &
的 Crate
这将避免复制并允许我们绑定到临时文件
friend ostream& operator<< (ostream& out, const Crate& c)
学习通常是关于良好的习惯和常识,更不用说你正在写的小例子了。
是的,在您的情况下,性能方面的按值传递不会改变任何内容。但这有两个问题:
- 习惯。你应该养成知道如何表达你的论点的习惯。如果不需要修改且不应该移动数据,则通过const引用传递;
- 按照你写的方式,你的 class 必须是可复制构造的。你的是,但并非总是如此。
至于作为标记的实际零 - 不要担心。没有任何意义。
我有一个 C++ 期中考试,我们的作业之一是编写一个 class,它重载了 <<
运算符,以便我们可以将 class 的私有字段打印到std::ostream
,像这样:
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
而他们传递它参考。
当然,如果 class 有动态分配的成员变量,我将不得不通过引用传递它的实例,但这里不是这种情况。
我知道 cppreference.com 中提供的示例使用了 const 引用,但是是否有任何严格的规则要求在执行此操作时必须使用 const 引用?
我知道我的解决方案将 weight
和 value
都复制到堆栈而不是只复制指向对象的指针,但是是 +4 字节(在 32 位系统的情况下)堆栈上真的有那么多问题,还是我遗漏了更严重的东西(比如某种内存泄漏)?
我也检查了这两个解决方案的反汇编,但我找不到任何能让我的解决方案值零分的东西。
我也问过我的教授,但他们开始谈论将其作为 const
传递,但我看不出这将如何使这个解决方案在工作/不工作方面变得更好。另一位教授告诉我 "this is syntactically completely incorrect." 但是它是用 Visual Studio 和 MinGW 编译的,所以我也无法理解。
另请注意,这是一门面向电气工程师的课程。
在c++中是否必须通过引用传递classes
没有
"Passing it as const" 太傻了,如果你按值传递,那么你将参数标记为 const 对外界来说并不重要。
尽量直接回答你的问题,按值取另一个class没有错。当对象较小时,最好按值传递。在您的情况下,典型 64 位平台上的大小差异为 0(每个 int 2 * 4 字节与一个 8 字节指针)。所以你的“+4 bytes on the stack”其实是不存在的,大小一样
我预测优化编译器会重写您的代码以按值获取 Crate
,即使您将其声明为按引用获取。这将是出于空间局部性原因和易于访问。如果传递的是指针,则需要跟随指针到达数据成员,这会增加一个步骤。
你的教授给你0分是错误的,除非课程中有明确要求所有运算符都必须带参考参数。 const Crate
与 Crate
的问题无关紧要。
你不应该得到 0 分,但你也不应该得到满分。
friend ostream& operator<< (ostream& out, Crate c)
每次调用时都会创建一个副本,这可能效率低下。为了避免那些你想通过引用传递的副本,比如
friend ostream& operator<< (ostream& out, Crate& c)
但这引入了一个新问题,您的第一个版本没有通过引用传递您需要为函数提供左值。你将无法像
那样使用它std::cout << Crate();
为了解决这个问题,我们可以采用 const &
的 Crate
这将避免复制并允许我们绑定到临时文件
friend ostream& operator<< (ostream& out, const Crate& c)
学习通常是关于良好的习惯和常识,更不用说你正在写的小例子了。
是的,在您的情况下,性能方面的按值传递不会改变任何内容。但这有两个问题:
- 习惯。你应该养成知道如何表达你的论点的习惯。如果不需要修改且不应该移动数据,则通过const引用传递;
- 按照你写的方式,你的 class 必须是可复制构造的。你的是,但并非总是如此。
至于作为标记的实际零 - 不要担心。没有任何意义。