将调用对象(this)的指针作为参数传递给 C++ 中另一个实例化方法的方法;

发布于 2024-10-21 17:35:01 字数 725 浏览 2 评论 0原文

我正在审查一些代码,并且多次偶然发现标题中描述的示例。然后,在从第二个对象调用外部方法时引用此传递的对象,甚至在其他地方更改,然后在另一个方法中再次通过引用使用。

最奇怪的是,第二个对象从传递的第一个对象调用方法,该第一个对象无论如何都创建了第二个对象。

我还没有做过类似的事情,但由于我对 C++ 比较陌生,我允许人们在使用具有如此多选项的语言进行编码时感到非常自由……

但是,主要问题是:这是常见的做法吗?有什么技术原因不做这样的事情吗?

我添加了一个简短的示例:

TypeReturned *ClassB::GetSomething( ClassA *objectA)   
{
        someMethod(wm);

        ClassC *objectC = new ClassC(objectA->method());

        PCS->method(……, &objectA->someMethod(), objectA);
}

此方法是从 objectA 调用的。 第一次打电话很正常。通过简单地传递需要的参数而不是完整的类和回调来解决第二个和第三个将更具可读性。 我还可以说,这两个类并没有真正相互通信,也没有交叉引用。

I'm reviewing some code and I have stumbled many times on examples as described in title. THen this passed object is referenced in calling outside methods from second object, even changed somewhere else and then again used by reference in another methods.

THe weirdest thing is that the second object calls methods from passed first object that created second anyway.

I haven't done similar stuff yet, but I since I am relatively new to C++ I allow possibility that people feel very free in coding with language with so many options...

However, the main question is: is that common practice? Is there any technical reason for not doing such stuff?

I have added a short example:

TypeReturned *ClassB::GetSomething( ClassA *objectA)   
{
        someMethod(wm);

        ClassC *objectC = new ClassC(objectA->method());

        PCS->method(……, &objectA->someMethod(), objectA);
}

This method is called from objectA.
First call is quite normal. The second and the third would be more readable to solve with simpe passing needing parameters, not the complete classes and callbacks.
I can also say, that those those 2 classes do not really communicate to each other and don't have cross-references.

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

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

发布评论

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

评论(3

不交电费瞎发啥光 2024-10-28 17:35:01

也许主要问题应该分为更多:这是将自身传递给 C++ 中另一个对象的常见且实用的解决方法吗?

这既常见又实用。很多时候,这是实现某件事的最自然的方式。例如,如果您希望父子对象可以从两端导航,最简单的方法是父对象在创建后将其自身 (this) 传递给子对象,以便子对象存储对父对象的引用。注册 self 进行回调(如观察者模式中)是另一个示例。

这在一般情况下很有用,而不是 C++ 特有的东西。

Perhaps main question should be divided into more: is this usual and practical workaround to pass itself to another object in C++?

It is both usual and practical. Quite often it's the most natural way to achieve something. For example if you want a parent-child navigable from both ends, it's easiest for the parent object to pass itself (this) to the child object after creation so that it stores the reference to parent. Registering self for callback (as in the observer pattern) is another example.

This is useful in general, not something specific to C++.

忘羡 2024-10-28 17:35:01

据我所知,这在技术上是完全没问题的,而且经常发生。有时,这是“最好”的方式,而且不管你信不信,也是最清晰的方式。

  • 皮特

AFAIK it's perfectly OK technically and happens all the time. Sometimes it's the "best" way and, believe it or not, the clearest way.

  • pete
巾帼英雄 2024-10-28 17:35:01

我认为(尽管我不能告诉并且很高兴被证明是错误的)您所描述的方案类似于 双重调度(C# 中的示例)。如果我是正确的,您会看到如下调用:

class LivenessPingMessage : public Message {
   public:

    void accept(Controller& c) {
      c.visit(this);
    }
}

class Controller {
  public:

  handleNetworkQueue() {
    while (true) {
      Messages::Message* m = networkLayer->getNextMessage();
      if (m != NULL) {
        m->accept(*this);
      }
    }
  }

  void visit(Messages::LivenessPingMessage* m) {
    //Do something
  }

}

class Message {
  public:
    virtual void accept(Controller& c) = 0;
}

这允许类 Controller 通过调用它们拥有的虚拟 accept() 方法来处理消息。然后,这些消息使用指向它们的控制器的指针来调用重载方法 visit(Message m)

这意味着消息只需要了解控制器,而不需要了解有关它们应该完成的任务的任何其他详细信息。控制器包含适当处理消息所需的所有逻辑。

它在喜欢双重调度的人中很常见,是公认的设计模型。

I think (Although, I can't tell and am happy to be shown wrong) that what you are describing is a scheme similair to double dispatch (Example in C#). If I am correct you are seeing calls like:

class LivenessPingMessage : public Message {
   public:

    void accept(Controller& c) {
      c.visit(this);
    }
}

class Controller {
  public:

  handleNetworkQueue() {
    while (true) {
      Messages::Message* m = networkLayer->getNextMessage();
      if (m != NULL) {
        m->accept(*this);
      }
    }
  }

  void visit(Messages::LivenessPingMessage* m) {
    //Do something
  }

}

class Message {
  public:
    virtual void accept(Controller& c) = 0;
}

This allows the class Controller to handle messages by calling the virtual accept() method they have. These messages then use the pointer to Controller they have been given to call the overloaded method visit(Message m).

This means that Messages only need to know about Controllers, not any other details about the tasks they are supposed to complete. The Controller contains all the logic needed to deal with the Message appropriately.

It is common amongst people who like double dispatch and is a recognised design model.

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