流行的(c ++)“错误:没有匹配函数来调用...”,虽然有点踢

时间:2014-03-13 01:47:27

标签: c++ class initializer-list

我在c ++工作。

我的班级animation.h如下:

class Animation
{
public:
    Animation(ofVec2f _startLoc, ofVec2f _endLoc, float _speed, float _accel);
    virtual ~Animation();
};

然后在sceneMusic.h我有另一个类调用animation class。

#include "animation.h"
class sceneMusic
{
    public:
        sceneMusic();
        virtual ~sceneMusic();
    private:
        Animation staveMotion;
};

sceneMusic.cpp

sceneMusic::sceneMusic()
{
    staveImg.loadImage("./sceneMusic/stave_white.png");

    staveMotion = Animation(ofVec2f(29, -staveImg.height()), \
                            ofVec2f(29, 249), 1, 0.1);
}

以上给出了以下(预期)错误:

src/awards/sceneMusic.cpp|3|error: no matching function for call to ‘Animation::Animation()’|
src/awards/sceneMusic.cpp|5|note: candidates are:|
src/Animation.h|14|note: Animation::Animation(ofVec2f, ofVec2f, float, float)|
src/Animation.h|14|note:   candidate expects 4 arguments, 0 provided|

我读了很多线索,建议我应该使用initializer lists并在sceneMusic.cpp

sceneMusic::sceneMusic()
    :Animation(ofVec2f(29, -staveImg.height()), \
               ofVec2f(29, 249), 1, 0.1)
{
    staveImg.loadImage("./sceneMusic/stave_white.png");
}

或类似的东西。 问题是staveImg的height只有在执行构造函数后才可用。

同样,班级sceneMusic不会继承班级animation,因此我不确定上述内容是如何运作的。如果我尝试运行上面的内容,我会

src/awards/sceneMusic.cpp|4|error: type ‘Animation’ is not a direct base of ‘sceneMusic’|
src/awards/sceneMusic.cpp|4|error: ‘((sceneMusic*)this)->sceneMusic::staveImg.ofImage_<unsigned char>::height’ cannot be used as a function|
src/awards/sceneMusic.cpp|5|error: no matching function for call to ‘Animation::Animation()’|
src/awards/sceneMusic.cpp|5|note: candidates are:|
...

我做错了什么?

谢谢你的帮助

2 个答案:

答案 0 :(得分:3)

嗯,第二次尝试的问题是你需要这样做:

sceneMusic::sceneMusic()
    :staveMotion(ofVec2f(29, -staveImg.height()), \
               ofVec2f(29, 249), 1, 0.1)

您可以在初始化列表中指定成员名称。只有在尝试调用特定的超类构造函数时才指定类名。 Animation不是sceneMusic的超类。

以下“没有用于调用Animation :: Animation()的匹配函数”,原因与初始化列表中根本没有任何内容的原因相同:staveMotion成员是仍尝试使用Animation的默认构造函数(就像声明变量Animation a;时使用默认构造函数一样),但Animation没有默认构造函数。

更正初始化程序列表中的错误可以解决这两个错误。

顺便提一下,关于height()的第二个错误:确保实际上有一个名为height()的成员函数。您没有显示代码,但该错误似乎表明您实际上有一个名为height的成员变量,而不是函数。

但是,上述仍然无法解决您必须首先致电loadImage的问题(感谢Chris在评论中提醒我这一点)。

最简单的解决方案是恢复第一次尝试,只为Animation提供默认(无参数)构造函数。一旦声明了非默认构造函数,编译器就不再为您生成默认构造函数,您必须显式声明/ define Animation::Animation()来提供它。这样,staveMotion可以使用一些默认值构建(并且不必在初始化列表中构建),然后再分配给适当的值。

顺便说一下,第二个选项不需要首先创建临时默认Animation(或者更重要的是,不需要你实现可能会破坏类不变量的默认构造函数),将staveImg作为sceneMusic的成员字段,给它一个构造函数,该构造函数接受图像文件名并加载图像,并在成员列表中的staveMotion之前声明它。您不需要Animation默认构造函数,您可以初始化初始化列表中的所有内容:

sceneMusic :: sceneMusic () :
   staveImg("./sceneMusic/stave_white.png"),
   staveMotion(ofVec2f(29, -staveImg.height()), ofVec2f(29, 249), 1, 0.1)
{
}

该选项的变体是提前构建图像并将其作为参数传递给sceneMusic构造函数。这不需要新的构造函数staveImg

CantChooseUsernames在评论中提出的第三个选项是使staveMotion成为指针。您可以将其初始化为NULL并在必要时构造new Animation(...),而无需默认构造函数。如果您这样做,请在完成后忘记delete。自动指针(例如std::unique_ptr<Animation>或其他智能指针之一(boost也有一些)可以使您更轻松。

答案 1 :(得分:2)

你需要一个默认的构造函数类动画,因为你提供参数构造函数,编译器不会为你生成一个

Animation() {}