用于放入在一组函数中传递的参数的结构

发布于 2024-10-28 00:58:27 字数 692 浏览 1 评论 0原文

我需要能够灵活地更改传递给不同函数的参数,具体取决于函数调用发生的位置,因此我决定将所有参数放在一个结构中,但是大多数参数本身都是结构或类我希望可以选择将它们保留为 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 传递给我的任何参数,但不确定到处使用原始指针是否是一个好主意?

I need the flexibility of being able to change parameters passed around to different functions, depending from where the call to the function happened, so I decided I'd put all my parameters in a struct, however most of these parameters are structs or classes themselves and I want to have the option of leaving them NULL, so I have to pass pointers to the structs/classes.

struct A
{
    otherB* b;  // NULL should be a valid value
    otherC* c;
};

However my question is now, passing A around these pointers will be the only thing copied, so if I did the following there would be a problem right?

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?

What would the best way to resolve something like this+ I want the flexibility of being able to pass NULL to any of my parameters, however not sure if using raw pointers everywhere is a good idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

忆依然 2024-11-04 00:58:27

要解决资源管理问题,您应该使用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 是在堆栈上分配的,因此我们将其包装在使用 null_deletershared_ptr 中,可能如下所示:

struct null_deleter {
    void operator()(void *) { }
};

这将不删除对象,它不会执行任何操作(这正是我们想要的堆栈分配对象)。但请记住,您必须确保 somec 的生命周期比 myA 长,否则您将遇到访问冲突。

To solve the problem of resource management, you should use boost::shared_ptr (or std::shared_ptr in C++0x).

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);

When myA goes out of scope, all resources are deallocated automatically. Since somec was allocated on the stack, we wrapped it in a shared_ptr that uses a null_deleter, that could look like this:

struct null_deleter {
    void operator()(void *) { }
};

This will not delete the object, it will do nothing (which is just what we want for stack-allocated objects). Keep in mind however, that you have to make sure that somec lives longer than myA, otherwise you will get access violations.

纵情客 2024-11-04 00:58:27

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..

boost::optional<> Allows you to test if the field is set or not.

Simple example (will not compile, I've not even remotely tested it, in theory this is how it should work)

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..
辞别 2024-11-04 00:58:27

您基本上必须分析所有权,即谁可以分配对象以及谁负责在不再使用对象后删除对象。

需要记住的一件重要事情是,如果混合动态分配的内容和放置在堆栈上的内容,则根本无法对它们应用删除,因为不可能删除堆栈上的内容。

一种方法可能是仅使用 new 并在 A 中定义一个析构函数来删除其所有指针。另一种方法可能是您注册稍后应删除的对象的地方。或者,您可以按照其他答案中的建议,使用现有的引用计数工具。

You basically have to analyze ownership, i.e. who can allocate and who is responsible for deleting object once they no longer is used.

One thing that is important to remember is that if you mix dynamically allocated things and things placed on the stack, you simply can't apply delete on them, as it's not possible to delete things on the stack.

One way could be to only use new and define a destructor in A that deletes all it's pointers. Another way could be a place where you would register objects that later should be deleted. Or you could go the route of using existing reference-counting tools, as suggested in other answers.

疑心病 2024-11-04 00:58:27

不,您对 myAsomec 范围的想法是错误的。您现在所拥有的没有任何问题 - 尽管我个人认为引用将是比指针更好的选择。

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
}

No, your idea of the scope of myA and somec are wrong. There's nothing wrong with what you have right now- although I personally think that references would be a superior option to pointers.

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
}
枕梦 2024-11-04 00:58:27

从你的描述来看并不清楚,但如果你遇到问题
因为 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 ) );

不知道它是否适合您的情况,但它通常
方便的。

It's not clear from your description, but if you're having a problem
because somec is going out of scope, it can only be because func is
saving a copy of the pointer. Don't do that: in funct, copy the object,
not the pointer.

PS: if most of the pointers are null most of the time, you should
consider using something like following syntactic sugar:

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 ) );

Don't know if it's appropriate for your situation, but it's often
convenient.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文