将指向临时对象(在堆上)的指针传递给函数的方法
C++ Ways to pass a pointer to a temporary object (on the heap) to a function?
我有一个函数,它接受一个指向自定义类对象的指针(实际上是指向基类的指针,以便多态工作)。然而,在调用例程中,该对象仅为该调用的目的所必需,即是临时的。例如:
class A { /** stuff */ };
class B : public A { /** stuff */ };
void doSomething( const A* const _p ) { /** stuff */ }
void callingRoutine()
{
A* tempPointer = new B;
doSomething( tempPointer );
delete tempPointer;
}
现在,因为我真的只需要B
类型的对象在doSomething
的调用中,有没有办法在一行中完成它?做
doSomething( new B );
造成内存泄漏(valgrind是这么说的)。还是
doSomething( &B );
是推荐的方法吗?后者可以编译,但会对将指针传递给临时对象发出警告。这是我想做的,但这样安全吗?
如果可以更改被调用函数的签名,则将其更改为:
void doSomething( A const& obj );
然后你可以用:
doSomething( B() );
如果不能,应该声明一个局部变量:
void callingRoutine()
{
B temp;
doSomething( &temp );
}
如果调用函数较长,并且如果temp是,则存在问题不立即销毁,你可以将其封装在附加的{...}
:
void callingRoutine()
{
{
B temp;
doSomething( &temp );
}
// More code here...
}
一般来说,如果这是必要的,你的函数是可能太长了
最干净的方法是:
B b;
doSomething(&b);
但是你真正应该写什么取决于doSomething
函数做什么。如果在callingRoutine
的末尾销毁b
是可以的,那么这是更快更干净的方法,因为在堆栈上分配比new
快,并且不需要在之后删除b
。
我有点惊讶居然没有人指出这个显而易见的事实:
void callingRoutine()
{
doSomething(&B());
}
我不得不怀疑整个设计需要传入一个指针指向一个对象,但当它完成后,你显然忽略了它操作的对象,但如果你确定你想要什么,你正在做什么,这似乎是最简单,最直接的方式来实现它。
在您的情况下,您可以使用自动变量(堆栈上)
void callingRoutine()
{
B obj;
doSomething( &obj );
} // obj is destroyed automatically
这没有给出警告。此外,只有当您确实希望在函数作用域之外长时间地引用/访问内存地址时,才应该使用new
。在函数块中,用new
分配是没有意义的。
请参考Bjarne页面上的链接,他在其中指出了与您的示例完全相同的示例。
顺便说一下,如果你只想要一行,那么解决方案将不干净,但这里有一个解决方案:
B obj; doSomething( &obj );
可能是下面的东西?
void doSomething( std::auto_ptr<A> _p ) { /** stuff */ }
void callingRoutine()
{
doSomething(std::auto_ptr<A>(new B));
}
解决问题的最简单方法是按如下方式更改代码:
void callingRoutine()
{
B temp;
doSomething( &temp );
}
这是有效的,因为你只需要多态访问doSomething(),这是保证的事实,你传递一个指针到temp通过它的地址。
将指针传递给临时对象通常是一个坏主意,因为该对象可能在被调用者完成使用之前被销毁。在您的示例中,doSomething()
应该在对象被删除或超出范围之前返回,因此,直到doSomething
不存储对对象的任何引用之前,这都不是问题。
可以在调用或表达式期间将临时值(r值)强制转换为l值:
template<class T>
inline T& l_value(T const& t)
{
return const_cast<T&>(t);
}
struct A {};
void doSomething(const A*);
void foo()
{
doSomething(&l_value(A()));
}
- 在C#中处理C++指针而不使用unsafe的最佳方法
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 对于C++中使用智能指针的指针算术限制,有没有一种变通方法
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 将成员函数指针作为参数传递给模板方法
- 通过函数指针定义类范围之外的方法
- 模板方法访问正向声明的类仅在没有此指针的情况下无法编译
- 如何访问由共享指针保存的类方法?
- 初始化指向类实例的智能指针并访问其方法
- 我无法使用C++指针指向类方法返回的 std::vector
- 如何在工厂方法中返回指向基于基础操作系统的派生类的有效指针
- 有没有将变量名称转换为双指针的简短方法?
- 在自定义 std::vector-like 容器中处理指针和非指针模板类型的最佳方法是什么?
- 如何在成为指向基类的指针后保留对子类方法的使用?
- 从纯虚拟类 (A) 派生的指针无法访问来自纯类 (B) 的重载方法
- 类指针方法崩溃程序
- 证明两指针方法有效(对和)
- Qt 删除指针方法
- 我如何将一些类的指针方法转换为指针函数