首页 > 解决方案 > 我的对象的构造函数被奇怪地解释了吗?

问题描述

我有一个对象声明Bitmap image(FileRead(filename))......真的很困惑?

当我将鼠标悬停filename在 Visual Studio 中时,它会给我工具提示FileRead filename,就好像我在参数列表中声明了一个新变量一样。当我将鼠标悬停在它上面时,image它给我的感觉Bitmap image(FileRead filename)就好像它是一个函数声明。这些是我唯一的线索,因为如果我尝试使用 image 的方法之一,编译器只会给我一个编译错误,确认image至少没有被解释为对象。

如果我将参数更改为 is ,Bitmap image(FileRead("strLiteral"))或者如果我添加第二个可选参数 so it's Bitmap image(FileRead(filename), 4),问题就会消失。也许其他构造函数之一令人困惑,但是......我相当确定这种歧义类型是它自己的编译错误类,我得到的是完全不同的?

我真的很困惑,这里可能发生了什么?

int main(int argc, char * argv[]){

    const char * filename = "image.png";

    Bitmap image(FileRead(filename));

    // using either of these instead works as intended for some reason
    Bitmap image(FileRead(filename), 4u);   
    Bitmap image(FileRead("image.png")); 

    // image.get*() generates the following compilation error: 
    // "Error   C2228   left of '.getY' must have class/struct/union"
    // "Error   C2228   left of '.getX' must have class/struct/union"

    for (uint32 y = 0; y < image.getY(); ++y) {  
        for (uint32 x = 0; x < image.getX(); ++x) {

        }
    }
    return 0;
}

这是 FileRead 和 Bitmap 的所有构造函数签名,以防这里的某些东西引起了麻烦。

class Bitmap {
    friend Mipmaps;
public:
    Bitmap();
    Bitmap(const Bitmap & other, bool flipY = false);
    Bitmap(Bitmap && other, bool flipY = false);
    Bitmap & operator=(const Bitmap & other);
    Bitmap & operator=(Bitmap && other);
    Bitmap(FileRead & file, uint16 byteDepth = 4u, uint16 heightForVolume = 0, bool flipY = false); 
    Bitmap(const uint8 * compressedImgData, uint32 imgDataLen, uint16 byteDepth, uint16 heightForVolume = 0, bool flipY = false);
    Bitmap(uint16 byteDepth, glm::u16vec2 size);
    Bitmap(uint16 byteDepth, glm::u16vec3 size);
    static Bitmap asBorrowed(uint8 * data, glm::u16vec4 size, TextureDim::Type dimensionality = TextureDim::dim2D);
    ...
    uint16 getX() const                 { return m_size.x; }
    uint16 getY() const                 { return m_size.y; }
};
class FileRead{
public:
    FileRead(const char * filename, bool textMode = false, uint32 bufferSize = 4096);
    ...
};

标签: c++constructor

解决方案


这是Most Vexing Parse的一个不太常见的情况,它的名字来源于与你类似的反应。

这个想法是,通过应用墨菲定律,如果有什么东西可以翻译错,它就会,所以如果变量的声明看起来像函数声明,那就是后者。

FileRead是一个类型名称,因此FileRead(filename)可以FileRead filename根据 C 和 C++ 中的声明语法来读取,所以你有一个名为的函数原型image

Bitmap image(FileRead filename);

推荐阅读