我想使用new
创建一个类的实例,但我想转换为引用以供使用指针以外的其他用法。目前我正在使用此行Foo& rf = *f;
进行明确转换,看起来有点傻。有没有更好,更优雅的方法来创建引用变量并引用new
创建的实例?
以下是一些显示我正在做的事情的代码,
class Foo{
public:
Foo(){
}
void printValue() {
cout << "This is Foo object " << endl;
}
};
int main() {
Foo* f = new Foo();
Foo& rf = *f;
rf.printValue();
f -> printValue();
}
答案 0 :(得分:1)
你可以这样写:
Foo* foo = new Foo();
Foo& fooRef = *foo;
在一行中:
Foo& fooRef = *new Foo();
但是,请注意,您应该稍后删除已分配的内存:
delete &fooRef;
我不建议您以这种方式编写代码,以避免内存泄漏。查看this answer了解更多详情。尽可能选择智能指针或容器。
答案 1 :(得分:1)
...转换为参考以供使用指针以外的其他用途。
我更喜欢我的代码中的引用(并避免使用指针)。主要是因为nullptr可能具有特殊含义(引用不会)需要一些思考来确认,下次我查看代码时。
我的解决方案是新建大于自动内存的对象,以便在适当的生命周期内获得指针。然后,我使用解除引用的指针调用using方法或函数。这使得指针(在生命周期开始时,例如main)保持不变,以后仍可用于删除。
// bigData used many places
void use1_of_Data (BigData_t& bigData, Small_t& sd) {
//... do something with data
}
void use2_of_Data (BigData_t& bigData, Small_t& sd) {
//... do something with data
}
//...
void use3_of_Data (BigData_t& bigData, Small_t& sd) {
//... do something with data
}
int main(int argc, char* argv[])
{
// ...
BigData_t* bd = new BigDta_t; // (sizeof(BigData_t) > autovar space)
Small_t sd;
{
assert(nullptr != bd);
// note - bd lasts the lifetime of program
use1_of_Data (*bd, sd);
use2_of_Data (*bd, sd);
//...
use3_of_Data (*bd, sd);
}
// what's new'd in main, is deleted in main
delete bd;
}
答案 2 :(得分:0)
正如其他人所说,如果Foo实例的非堆内容不是很大,以至于Foo实例本身需要在堆上分配,那么最好只使用堆栈: / p>
Foo foo;
foo.printValue();
但是,如果由于某种原因确实需要在堆上进行分配,那么在普通指针中保持对它的唯一引用是危险的,因为如果任何代码抛出异常,它将会永远不会被解除分配。事实上,大多数现代C ++指南建议不要使用普通指针来拥有数据:
Foo * fooPtr = new Foo();
doSomething(); // If an exception is thrown here, the Foo never gets deallocated!
Foo& foo = *fooPtr;
foo.printValue(); // If printValue throws an exception, the Foo never gets deallocated!
delete foo;
如果您不熟悉这类问题,我建议使用Google搜索RAII(&#34;资源获取是初始化&#34;)这是了解用C ++编程时的一个重要概念。
在这种情况下实现RAII的一种简单方法是使用智能指针(std :: shared_ptr或std :: unique_ptr)。
额外的引用变量仍然有助于避免必须使用箭头操作符来调用smartpointer上的函数。我不同意其他一些不会在本地引用中绑定本地引用的问题的回答者。我更喜欢尽可能使用引用,因为当我使用引用时,我可以确定引用不是null(引用应该始终引用实际对象),而当我使用指针(甚至是智能指针)时我必须始终小心我的代码正确处理指针为空的情况。当指针初始化发生在指针的使用附近时,这可能不是什么大问题,但是当它们分开时,很难通过代码跟踪以确保指针不能为空。引用使这个自我记录。
我认为首先确保指针或智能指针值不能为空,然后将本地引用绑定到指向的值通常很有用,因为我可以自由地使用引用无需担心每次使用它是否为空的可能性:
std::unique_ptr<Foo> fooPtr = std::make_unique<Foo>(/* Foo constructor args go here */);
doSomething(); // Now if an exception thrown here, Foo gets deallocated.
Foo& foo = *fooPtr; // We know the pointer is not null here (it just
// got returned from make_unique which
// didn't throw a bad_alloc exception) so it's
// safe to bind a reference to it here.
// Also, this reference has lifetime less than the
// smart pointer, so will never outlive it.
// .. many lines of code later ..
foo.printValue(); // No need to worry about null here.
// If exception thrown here, the unwinding of the stack
// causes fooPtr to deallocate Foo.
// No need to call delete here.
// fooPtr will automatically deallocate Foo when it goes out of scope.
答案 3 :(得分:-1)
如果我们谈论优雅,我建议你使用shared_ptr吗?
#include <iostream>
#include <memory>
using namespace std;
class Foo{
public:
Foo(){
}
void printValue() {
cout << "This is Foo object " << endl;
}
};
int main(int argc, char *argv[])
{
Foo* f = new Foo();
std::shared_ptr<Foo> mySharedPtr(f);
f->printValue();
mySharedPtr.get()->printValue();
return 0;
}