cari

Rumah  >  Soal Jawab  >  teks badan

c++多态性测试代码中遇到了类型限定符不兼容


编程菜鸟,在学习c++多态性的过程中,写了这样的测试代码,这里会有类型限定符不兼容。
当我在抽象基类的函数声明后添加上const后,就不会出现类型不兼容,这是为什么?

PHP中文网PHP中文网2803 hari yang lalu442

membalas semua(3)saya akan balas

  • PHP中文网

    PHP中文网2017-04-17 13:22:14

    const限定的变量以及其引用只能调用const限定的成员函数
    const限定代表变量的值不会发生改变,要想不改变变量的值则只能调用const修饰的成员函数

    balas
    0
  • 高洛峰

    高洛峰2017-04-17 13:22:14

    你的问题其实与多态无关,要解答你这个问题需要两个方面的知识点。

    1. 成员函数的this指针

    首先,类的成员函数内要访问类的成员,需要通过this指针访问(名称不冲突时可省略),在通过一个对象调用成员函数的时候会将对象本身通过this指针传递给成员函数。例如:

    class A {
    public:
        explicit A(int xx = 0) : x(xx) {}
        int get() { return x; }
        void set(int xx) { x = xx; }
    private:
        int x;
    };
    
    int main() {
        A a;
        a.set(10);  // a.x = 10
        int i = a.get();  // i = 10
    }

    为什么我能在a.get()函数里访问对象a的成员x?就是通过这个this指针。在通过a调用a.get()的时候,编译器会把对象a的地址赋值给this指针,这里的this指针的类型是A *const。而在get()函数内,return x;这个语句其实相当于return this->x;,这样我们就能够通过a.get()来访问对象a的成员x了。

    同理,为什么a.set(10);能够把对象a的成员x赋值成10?也是通过this指针。x = xx;就相当于this->x = xx;

    以上两种情况下,由于对于x的解析不可能出现歧义,所以this指针可以省略。但是,如果我想在成员函数set的参数里使用与成员x同样的变量名该怎么办?依然通过this指针进行区分。我们可以把成员函数set的定义修改如下:

    A::void set(int x) { this->x = x; }

    这里的this指针就不能省略了,否则的话,写成x = x;就会出现歧义,编译器无法解析x到底是函数的参数还是对象的成员。

    2. const成员函数

    考虑一个情况,在前面的例子中,我们的对象a是一个非常量对象,如果我们想使用类A声明一个常量对象怎么办?例如

    int main() {
        const int ci = 10;
        int i = ci;
        const A ca(5);  // ca.x = 5
        int j = ca.get();  // 编译错误
    }

    对于内置类型,可以直接定义常量ci,并且使用它的值。那对于我们自己定义的类A,我们也可以采用相同的方法定义常量ca,通过ca.get()获取对象a的成员x的值。

    但是,在使用成员函数获取它的数据成员x的值的时候,我们实际上仍然通过this指针来访问成员x,问题是,此时this指针不是const A *const类型,而是A *const类型。我们知道,不可以通过非常量的指针来访问常量的内容,即

    const int ci = 5;
    int *p = &ci;         // 错误
    const int *cp = &ci;  // 正确

    那么如何通过this指针来访问成员x呢?我们需要想个办法使this指针变成const A *const类型。办法就是,在类的成员函数声明末尾添加const关键字,这样就表示该成员函数是 const成员函数,而函数内this指针是常量类型。举例来说,我们可以重载get()方法:

    int A::get() const { return x; }

    此时,

    int j = ca.get();  // j = 5

    就会正常运行了。

    应用

    具体到你的问题来说,

    当我在抽象基类的函数声明后添加上const后,就不会出现类型不兼容,这是为什么?

    store_file()函数内,其参数img_file是一个常量引用类型,想要通过一个常量对象调用成员函数,就需要这个对象的成员函数的this指针也是常量类型。

    当你在抽象基类的get_file_name()函数声明后面添加上const以后,这个函数内的this指针就从Image_file *const类型变成了const Image_file *const类型,此时return file_name + std::string(".gif");里的成员file_name是通过常量类型的this指针调用的。从而满足了上述要求。

    balas
    0
  • PHP中文网

    PHP中文网2017-04-17 13:22:14

    const对象只能调用const成员函数

    balas
    0
  • Batalbalas