【问题标题】:Calling object method during creation c++在创建c ++期间调用对象方法
【发布时间】:2019-07-17 07:31:01
【问题描述】:

假设我有一个对象,比如A,就像这样

class A {
  private:
    int x;
  public:
    A(){};
    ~A(){};
    void sayA() {
      std::cout << "A" << std::endl;
    }
};

现在,如果我有一个指向 A 的指针向量

std::vector<A *> As;

我可以将Anew 实例推回向量,同时访问sayA 方法吗?

像这样

As.push_back(new A()->sayA());

只是指出在这种情况下A 不是我创建的对象,它是图形库的一部分

【问题讨论】:

  • 它们不被称为“同时”。你的最后一行相当于auto a = new A(); auto b = a-&gt;sayA(); As.push_back(b);
  • 'new A()->sayA()' 的结果是无效的。你的向量用 A* 参数化。由于 sayA 返回 void - 不,你不能。如果您将其更改为 'const A* sayA() {... return this;}' 那么您可以尝试使用 const_cast。但你最好不要这样做。
  • 请定义“创建期间”。有一个叫做构造函数的东西,它运行的正是里面的东西。但实际上,无论你在调用new之后写什么代码都放在构造函数调用的后面,所以本质上没有区别。

标签: c++ instantiation


【解决方案1】:

你可以(ab)在 C++17 中使用emplace_back

As.emplace_back(new A())->sayA();

但实际上,IMO 这更清楚:

As.push_back(new A());
As.back()->sayA();

【讨论】:

  • 哦,这是有道理的,因为.back() 返回对向量中最后一个元素的引用。谢谢!
  • @Rakete1111 我猜你的意思正好相反
  • @SOFe 哦;不,OP提到了迭代器并在之后编辑了评论。 :)
  • 如果它是对最后一个条目的引用,也许您需要双重 deref? AsA * 的向量,而不是 A
  • @SOFe 如果back() 返回了一个迭代器(一次通过迭代器,一次通过A*),你需要双重deref。但由于它是对最后一个对象的引用,所以它是一个 A*&amp;,它只需要一个 deref。
【解决方案2】:

你可以让sayA 返回一个指向实例的指针。像这样:

auto sayA() {
  std::cout << "A" << std::endl;
  return this;
}

然后按如下方式插入实例。

As.push_back((new A())->sayA());

但除了让它工作之外,这很尴尬且难以阅读。考虑使用智能指针向量并先插入,然后调用方法。如果sayA 是对象构造的一部分,则从A 的构造函数中调用它。

【讨论】:

  • 我有点想知道工厂类(如果函数调用变得复杂)是否是一种可以想象的方法。想听听您对此的看法。
  • @StackDanny 嗯,我们应该如何从 OP 的 sn-p 判断呢?如果构造变得复杂,工厂类可能值得,但在这里,它并不复杂?
  • 我的意思是纯粹假设。 (不建议您在答案中对此进行扩展):)
  • @StackDanny 好的...如果sayA 是构造的实现细节,它应该由A::A 调用。如果是构造后可以调用的公共成员函数,则应单独调用。在这两种情况下,我都不会使用外部功能进行构建。
【解决方案3】:

基本上是的,如果您确保sayA() 将返回this,因为push_back() 将期望指向A 的指针,而不是sayA() 的当前返回类型的void .如果您返回任何其他指向A 的指针,那么您将泄漏新分配的对象,因为无法删除它。

但是

为什么你想拥有指向A 的指针向量并且如果你可以只拥有std::vector&lt;A&gt; As; 然后你可以按照其他答案的建议调用sayA(),那么以后删除它们会很头疼。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    • 2013-01-24
    • 1970-01-01
    • 1970-01-01
    • 2018-03-28
    • 1970-01-01
    相关资源
    最近更新 更多