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

时间:2013-12-16 18:30:28

标签: c++

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

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

1 个答案:

答案 0 :(得分:3)

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

SimpleGrayImage::SimpleGrayImage(SimpleGrayImage&)

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

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

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

编辑:有关右值的更多信息,您可以查看this link。 Rvalues可以转换为const SimpleGrayImag& a = apply_mask(),因为const确保您无法对a进行更改,因此编译器可以安全地为您提供该本地内存的地址。没有const的定义只能用于这样的左值:

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

最好的方法是在所有不希望它们作为输出参数的参数上使用const。您也可以使用const和非const两个版本创建函数,并且大多数情况下编译器都会理解您,但是应该避免使用它,因为代码更难以阅读和理解。