在C++中创建对象时调用对象方法

3

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

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

现在,如果我有一个指向 A 的指针向量。
std::vector<A *> As;

我能够在访问sayA方法的同时向vector中推送A类的new实例吗?

像这样:

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

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


它们不被称为“同时”。你的最后一行相当于 auto a = new A(); auto b = a->sayA(); As.push_back(b); - SOFe
"new A()->sayA()" 的结果是 void。你的 vector 使用 A* 作为参数。由于 sayA 返回值为 void,所以你不能这样做。如果将其更改为 "const A* sayA() {... return this;}",那么你可以尝试使用 const_cast。但最好不要这样做。" - Victor Gubin
请定义“创建期间”。有一个叫做构造函数的东西,它会精确地运行其中的内容。但实际上,在调用new之后编写的任何代码都会被放置在构造函数调用的后面,因此基本上没有区别。 - SOFe
3个回答

8
你可以在C++17中(滥用)使用emplace_back
As.emplace_back(new A())->sayA();

但实际上,在我看来,这个更为明确:
As.push_back(new A());
As.back()->sayA();

哦,这很有道理,因为.back()返回向量中的最后一个元素的引用。谢谢! - sassy_rog
@Rakete1111 我猜你的意思是相反的。 - SOFe
@SOFe 噢;不,原帖提到了迭代器,后来进行了编辑。 :) - Rakete1111
如果这是对最后一个条目的引用,也许您需要双重解引用?“As”是“A *”而不是“A”的向量。 - SOFe
2
@SOFe 如果 back() 返回一个迭代器,你需要进行双重引用(一次是遍历迭代器,一次是遍历 A*)。但由于它是指向最后一个对象的引用,所以它是 A*&,只需要一次引用。 - Rakete1111

6
你可以让sayA返回指向实例的指针。就像这样:
auto sayA() {
  std::cout << "A" << std::endl;
  return this;
}

然后按以下方式插入实例。
As.push_back((new A())->sayA());

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

我有点想知道,如果函数调用变得复杂,工厂类是否是一种可行的方法。很想听听您的想法。 - Stack Danny
@StackDanny 嗯,我们怎么能从 OP 的片段中判断呢?如果构造变得复杂,工厂类可能是值得的,但在这里,它并不复杂。 - lubgr
1
我是在纯粹假设的情况下说的。(并不是建议你在回答中进一步扩展) :) - Stack Danny
@StackDanny 好的...如果 sayA 是构造函数的实现细节,那么应该由 A::A 调用。如果它是一个公共成员函数,在构造之后可以被调用,那么应该单独调用。在这两种情况下,我不会选择外部功能来进行构造。 - lubgr

0

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

但是

为什么要拥有指向A的指针向量,并在以后头疼删除它们,如果您可以只拥有std::vector<A> As;,然后您可以像其他答案建议的那样调用sayA()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接