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

Create an inline object and pass as parameter

本文关键字:对象 参数传递 一个 创建      更新时间:2023-10-16

嗨,我来自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});
heap.insert(new Food);

本身C++语法有效。它构造 Food 类的新实例,并将其传递给 heap 的 insert(( 方法。

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

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

总结一下:

heap.insert(new Food);

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

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

最后,将适当的复制构造函数添加到类定义中或通过引用传递它。

下面是一个示例:

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概念,这是非常强大的;)

如果函数参数是按值或常量引用,并且您传递的类型可用于构造对象,则可以直接传递它。例如:

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