如何从函数调用中创建对象变量

How do I create an object variable from a function call?

本文关键字:创建对象 变量 函数调用      更新时间:2023-10-16

我们使用的是教授编写的自定义图像类。我可以加载像这样的图像

SimpleGrayImage in("images/uni01.pgm");

现在我有一个功能,看起来像这个

SimpleGrayImage apply_mask(SimpleGrayImage &img,SimpleFloatImage &mask){

我也可以使用类似apply_mask(...).show(); 的方法

但我不被允许做这个SimpleGrayImage img = apply_mask(...);

是我遗漏了什么,还是我们的教授忘记添加另一个构造函数?

test.cpp:133:43: error: no matching function for call to ‘SimpleGrayImage::SimpleGrayImage(SimpleGrayImage)’
   SimpleGrayImage img = apply_mask(in,mask);
                                           ^
test:133:43: note: candidates are:
In file included from SimpleFloatImage.h:13:0,
                 from aufgabe11_12_13.cpp:13:
SimpleGrayImage.h:110:2: note: SimpleGrayImage::SimpleGrayImage(const string&)
  SimpleGrayImage(const std::string& filename);
  ^
SimpleGrayImage.h:110:2: note:   no known conversion for argument 1 from ‘SimpleGrayImage’ to ‘const string& {aka const std::basic_string<char>&}’
SimpleGrayImage.h:91:2: note: SimpleGrayImage::SimpleGrayImage(SimpleGrayImage&)
  SimpleGrayImage(SimpleGrayImage &img);
  ^
SimpleGrayImage.h:91:2: note:   no known conversion for argument 1 from ‘SimpleGrayImage’ to ‘SimpleGrayImage&’
SimpleGrayImage.h:86:2: note: SimpleGrayImage::SimpleGrayImage(int, int)
  SimpleGrayImage(int wid, int hig);
  ^
SimpleGrayImage.h:86:2: note:   candidate expects 2 arguments, 1 provided
SimpleGrayImage.h:80:2: note: SimpleGrayImage::SimpleGrayImage()
  SimpleGrayImage();
  ^
SimpleGrayImage.h:80:2: note:   candidate expects 0 arguments, 1 provided

从错误中,我可以看到复制构造函数的定义不正确:

SimpleGrayImage::SimpleGrayImage(SimpleGrayImage&)

这将不会被调用,因为从函数apply_mask返回的值不是局部变量,而是右值。

为了使构造函数获取右值,您需要将复制构造函数的签名更改为

SimpleGrayImage::SimpleGrayImage(const SimpleGrayImage&)//note the new const

编辑:有关右值的详细信息,您可以查看此链接。R值可以转换为const SimpleGrayImag& a = apply_mask(),因为const确保您不能更改a,因此编译器可以安全地为您提供该本地内存的地址。没有const的定义只能用于这样的lvalues:

SimpleGrayImag a;//this is an lvalue;
SimpleGrayImag b = a;

最好的方法是对所有不希望它们成为输出参数的参数使用const。此外,您还可以使用const和non-const两个版本生成函数,大多数时候编译器都会理解您,但应该避免这样做,因为代码更难阅读和理解。