以这种方式返回对新创建的对象的引用,这是一种安全的做法
Is returning a reference to the newly created object this way, a safe practice?
我说的是公共成员函数invert
和invert_version2
,它们将分数对象作为参数,并返回一个新的分数对象,该对象是参数对象的逆对象。
class fraction {
public:
fraction(long l1, long l2) {
num = l1;
den = l2;
}
const fraction& inverse (const fraction& f) {
return fraction(f.den,f.num);
}
const fraction& inverse_version2 (const fraction& f) {
return new fraction(f.den,f.num);
}
private:
long num;
long den;
};
这是100%安全的做法吗?这就是我的想法,如果我错了,请纠正:函数inverse
在堆栈上创建一个新的分数对象,即使返回了引用,一旦程序执行控制(有更好的术语吗?)退出该函数,内存中保存新创建的分数对象数据成员的值就会丢失,并被垃圾值取代(或者它们不是??)。
然而,函数inverse_version2
动态地创建分数对象,因此是101%安全的。
请澄清在前一种情况下(在堆栈上创建的分数对象)是否确实丢失了值。
这两个版本都是错误的。在第一种情况下,您将UB作为对本地对象的返回引用,而在第二种情况下它甚至不会编译。如果您试图修复第二个函数的幼稚方式,如取消引用指针,您将得到内存泄漏。因此,100%安全的变体是:
fraction inverse (const fraction& f) {
return fraction(f.den,f.num);
}
PS如果你想返回一个指向动态分配对象的指针,请返回一个智能指针:
std::unique_ptr<fraction> inverse_ptr( const fraction& f) {
return std::make_unique<fraction>(f.den,f.num);
}
-
你正在返回一个临时的引用,你被吐司了:
const fraction& inverse (const fraction& f) { return fraction(f.den,f.num); }
-
您是否返回一个指向动态分配对象的指针或引用?决定并更正代码
不管怎样,两者都不是一个好主意。const fraction& inverse_version2 (const fraction& f) { return new fraction(f.den,f.num); }
相反,您应该做的只是按值返回(并依靠RVO/NRVO来消除副本/移动),或者消除任何复制的机会
或者,如果对象真的那么大,通过std::unique_ptr
。
fraction inverse_v1(const fraction& f) { // Uses RVO / NRVO to eliminate temporaries
return fraction(f.den, f.num);
}
fraction inverse_v2(const fraction& f) { // no temporaries at all
return {f.den, f.num};
}
std::unique_ptr<fraction> inverse_v3(const fraction& f) { // smart-pointer
return {new fraction(f.den, f.num)};
}
相关文章:
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 有没有一种方法可以在编译时获得作用域类名
- 对于C++中使用智能指针的指针算术限制,有没有一种变通方法
- 一种在C++中读取TXT配置文件的简单方法
- 有没有一种简单的方法来检查C++中的不安全表达式
- 是否有一种安全的方法可以断言字符串视图是否以 null 终止?
- 一种安全、符合标准的方法,使类模板专用化仅在实例化时才无法使用"static_assert"进行编译
- 解释Java作为一种安全语言?
- 这是否是一种传递临时对象的安全方式
- 以这种方式返回对新创建的对象的引用,这是一种安全的做法
- 有没有一种安全的方法可以迭代 std::unique_ptr<int[]>?
- 有没有一种安全的方法可以在不触发溢出的情况下获得有符号整数的无符号绝对值
- 是否有一种方法可以机械地识别在移出对象上哪些操作是安全的
- 在c++中是否有一种安全的方式来执行来自用户/客户端的代码?
- 我如何使连续内存以一种安全的方式表现多态
- 线程安全队列是一种好方法吗?
- C++ - 一种确保调用全局清理函数的异常安全方法
- while(stringstream >> var1 >> var2)是一种安全的做法吗?