我需要能够灵活地更改传递给不同函数的参数,具体取决于调用函数的位置,所以我决定将所有参数放在struct中,但是大多数参数都是结构或者类本身,我希望可以选择将它们保留为NULL,所以我必须将指针传递给结构/类。
struct A
{
otherB* b; // NULL should be a valid value
otherC* c;
};
但是我现在的问题是,围绕这些指针传递A将是唯一被复制的东西,所以如果我做了以下就会出现问题吧?
void func(A& a) //non const cause I wanna change contents of A.
{
a.b = new b();
}
A myA;
otherC somec; // all these are currently automatic variables in my pgm.
myA.c = &somec;
func(myA); //myA goes out of scope? so I've lost all pointers assigned and since somec is out of scope too, I have a problem?
解决类似问题的最佳方法是什么+我希望能够灵活地将NULL传递给我的任何参数,但不确定是否在任何地方使用原始指针都是个好主意?
答案 0 :(得分:4)
要解决资源管理问题,您应该使用boost::shared_ptr
(或C ++ 0x中的std::shared_ptr
)。
struct A
{
boost::shared_ptr< otherB > b;
boost::shared_ptr< otherC > c;
};
void func(A& a)
{
a.b = boost::make_shared< otherB >();
}
A myA;
otherC somec;
myA.c = boost::shared_ptr< otherC >(&somec, null_deleter());
func(myA);
当myA
超出范围时,将自动释放所有资源。由于somec
已在堆栈上分配,因此我们将其封装在使用shared_ptr
的{{1}}中,如下所示:
null_deleter
这将不删除对象,它将什么都不做(这正是我们想要的堆栈分配对象)。但请注意,您必须确保struct null_deleter {
void operator()(void *) { }
};
的有效期超过somec
,否则您将违反访问权限。
答案 1 :(得分:1)
boost::optional<>
允许您测试字段是否已设置。
简单的例子(不会编译,我甚至没有对它进行远程测试,理论上它应该是如何工作的)
struct params
{
boost::optional<int> a;
boost::optional<foo> b;
boost::optional<bar> c;
};
void func(params& p)
{
if (p.a)
{
// do stuff with a
}
if (p.b)
{
// do stuff with b
}
if (p.c)
{
// do stuff with c
}
else
p.c = bar(); // again copy constructed and now initialized...
}
params p;
p.a = 1;
p.b = foo(); // copy constructed, however you can store a reference in the optional too.
// c is uninitialized
func(p);
// when p goes out of scope, everything is gone..
答案 2 :(得分:0)
您基本上必须分析所有权,即一旦不再使用对象,谁可以分配以及谁负责删除对象。
重要的是要记住,如果你混合动态分配的东西和放在堆栈上的东西,你就不能对它们应用delete
,因为它不可能删除堆栈上的东西。
一种方法可能是只使用new
并在A
中定义一个删除所有指针的析构函数。另一种方法可能是您将注册以后应删除的对象的位置。或者您可以使用现有的引用计数工具,如其他答案所示。
答案 3 :(得分:0)
不,您对myA
和somec
范围的看法是错误的。你现在拥有的东西没有任何问题 - 尽管我个人认为引用对于指针来说是一个更好的选择。
void func(A& a) //non const cause I wanna change contents of A.
{
a.b = new b();
}
int main() {
A myA;
otherC somec; // all these are currently automatic variables in my pgm.
myA.c = &somec;
func(myA);
// myA and somec are still perfectly in scope to be saved, or deleted, or w/e as you like
}
答案 4 :(得分:0)
从您的描述中不清楚,但如果您遇到问题 因为somec超出了范围,所以它只能是因为func 保存指针的副本。不要这样做:在功能,复制对象, 不是指针。
PS:如果大多数时候大多数指针都是空的,你应该这样做 考虑使用类似下面的句法糖:
struct A
{
// pointer members...
A() : // ... set all pointers to null...
A& withB( B const& someB ) { otherB = &someB; return *this ; }
A& withC( C const& someC ) { otherC = &someC; return *this ; }
// And so on for all of the rest of the pointers.
};
func( A().withC( somec ) );
不知道它是否适合您的情况,但通常是这样 方便。