创建一个内联对象并作为参数传递

Create an inline object and pass as parameter

您好,我来自 Java,以下是有效的:

System.out.println(new String("Hello World"));

有没有C++等同于在构造函数中创建一个对象或指针,同时将其作为参数传递如。

heap.insert(new Food);

是的。例如

std::vector<Food> c;
c.emplace_back(constructor arguments for Food);

一般来说,最常见的情况是对象不作为指针提供给方法。

如果 heap.insert 接受常量引用:

void insert(const Food& val);

然后您可以将它与临时或现有的 Food 参数一起使用,例如

heap.insert(Food{});

var auto foo = Food{constructor arguments};
heap.insert(foo);
heap.insert(Food(constructor arguments));

或者在某些情况下甚至

heap.insert({constructor arguments});

是的。您必须定义一个 class,一个接受参数的构造函数,然后是一个接受 class 实例的函数,仅此而已。

最后,向 class 定义添加一个适当的复制构造函数或通过引用传递它。

下面是一个例子:

struct S {
    S(int x) { this->x = x; }
    int x;
};

void fn(S s) { }
void cfn(const S &s) { }

int main() {
    fn(S{42});
    cfn(S{42});
}

请注意,在这种情况下使用 new 是导致内存泄漏的最简单方法之一,因此请注意!!

你举的例子太简单了。

cout << string("hello World");
// not necessary to contruct a string, but to show that it can be done on the spot

heap.insert(Food()); // construct a Food on the spot...

但一般来说,如果你在 Java 中谈论匿名 类 和类似的东西,C++ 有这个东西,它也有 lambda 非常强大的概念;)

heap.insert(new Food);

in 本身就是有效的 C++ 语法。它构造了一个 Food class 的新实例,并将其传递给堆的 insert() 方法。

但是,从 Java 过渡到 C++ 时,您需要了解的关键根本区别在于,您的 C++ 应用程序完全负责管理所有对象的生命周期。在 Java 你不需要考虑它。一旦某个对象不再在任何地方被引用,它就会在某个时候被 Java 的垃圾收集器销毁。

C++ 让您负责管理每个对象的生命周期。每当您的应用程序不需要您在此处使用 new 运算符构造的对象时,它应该是 deleted,否则您将泄漏内存。

总结一下:

heap.insert(new Food);

只是故事的一半。 new 运算符将构造您的新 class 实例,并且您的 heap 对象的 insert() 方法可能以某种方式存储指向新 class 实例的指针。在某个地方,您迟早需要 delete 那个 class 实例。

如果函数参数是传值或者是const引用,而且你传递的类型可以用来构造对象,你可以直接传递。例如:

void print(const std::string& str);

int main()
{
    print("Hello world");
}

std::string 有一个可以接受字符串文字的构造函数,因此代码编译,创建一个临时字符串对象,相当于:

print(std::string("Hello world"));

如果构造函数有多个参数,可以直接在函数调用中创建一个临时对象。例如:

void myfunc(const MyClass& c);

myfunc(MyClass(param1, param2));

在 Java 中,正在使用 new 创建新对象。在 C++ 中,new 不是创建新对象所必需的,应尽可能避免,因为它更难避免内存泄漏。这是来自 Java 的程序员最常犯的错误之一。

std::string text;
MyClass c;
c.do_something();

此代码完全有效。 textc 是有效对象。

std::string *text = new std::string();
MyClass *c = new MyClass();
c->do_something();
delete text;
delete c;

此代码也有效*。但是需要更多的输入,如果忘记删除它们,就会出现内存泄漏。

*编辑:实际上它不是异常安全的!更有理由避免 new!