创建一个新对象并传入方法参数

M-R*_*M-R 5 c++ oop parameters methods instantiation

在Java中,我们可以像这样在其参数内创建一个新对象并将其传递给方法:

wrapper.set_state( new Medium() );
Run Code Online (Sandbox Code Playgroud)

在C ++中,这等效于什么?我想我可以先创建对象然后再传递它,但是能够在参数中创建它似乎更加整洁。

kfs*_*one 5

在Java中

wrapper.set_state( new Medium() );
Run Code Online (Sandbox Code Playgroud)

创建一个新的引用计数的Medium实例,并将其通过引用传递给包装器的set_state函数。

在C ++中,以上代码在技术上是有效的,在包装器类中,set_state将定义为:

void set_state(Medium* medium);
Run Code Online (Sandbox Code Playgroud)

但是,您要做的就是将非引用计数的指针传递给Medium的新实例。您将负责确保delete稍后再执行。如果所有set_state都这样做:

void set_state(Medium* medium)
{
    this->medium = medium;
}
Run Code Online (Sandbox Code Playgroud)

每当您再次调用set_state时,都会引入内存泄漏。在C ++中,当您像这样覆盖原始指针时,没有引用计数。如果没有人再指向分配,则分配将丢失/泄漏。

您可能希望通过引用传递对象:

void set_state(const Medium& medium)
{
    this->medium = medium;  // copy
}
Run Code Online (Sandbox Code Playgroud)

通过以下方式调用:

Medium m;
// populate m
wrapper.set_state(m);

// or

wrapper.set_state(Medium());
Run Code Online (Sandbox Code Playgroud)

或者您可以按值传递:

void set_state(Medium medium)
{
    this->medium = medium;  // copy
}

// invocation:

Medium m;
// populate m
wrapper.set_state(m);  // copy
Run Code Online (Sandbox Code Playgroud)

尽管这是一个副本,但是在某些情况下,编译器可以淘汰其中一个副本(请参阅http://ideone.com/gNICYt

如果您绝对需要使用一个指针(有些东西将引用完全相同的Medium实例),则可能需要考虑使用std::shared_ptr提供引用计数的指针。

#include <memory>

struct Medium {};
class Wrapper {
    std::shared_ptr<Medium> medium;

public:
    void set_state(std::shared_ptr<Medium> medium) {
        this->medium = medium;  // if we'd called it m_medium, or medium_
        // we could just have written
        // m_medium = medium; or medium_ = medium;
    }
};

int main(void) {
    Wrapper w;
    w.set_state(std::make_shared<Medium>());

    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Isa*_*aac -1

这取决于参数的类型,请考虑以下因素:

  • 值参数:void set_state(Medium)移动-用临时的方式初始化它,即使用set_state(Medium())
  • 右值引用参数:void set_state(Medium&&),将其绑定到引用一个新构造的临时值,即use set_state(Medium())(这与值参数情况语法相同,但语义略有不同)
  • 左值引用参数:void set_state(Medium&),将其传递给新分配的对象的引用,即使用set_state(*new Medium())
  • 指针参数:void set_state(Medium*),向其传递一个指向新分配的对象的指针,即使用set_state(new Medium())

如果参数类型具有任何constorvolatatile修饰符,以及使用非模糊基类型的类型声明参数,则同样适用Medium


注意:使用时要小心new,与 Java 不同,C++ 不需要自动垃圾回收,因此您需要确保对象在不再需要时而不是之前被删除。(最安全的事情是不使用delete您的对象,但这只会浪费内存)

另请注意,由于 C++ 与 Java 非常不同(在语义方面),我建议阅读一本好书或其他一些有关该语言的资源,而不是就您不理解的所有内容提出问题,因为您可能会错过一些重要的差异这样就会产生灾难性的结果。