c++多态性测试代码中遇到了类型限定符不兼容
PHP中文网
PHP中文网 2017-04-17 13:20:14
0
3
463


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

PHP中文网
PHP中文网

认证0级讲师

reply all(3)
Ty80

Const-qualified variables and their references can only call const-qualified member functions
Const-qualified means that the value of the variable will not change. If you want to not change the value of the variable, you can only call const-modified member functions

小葫芦

Your question actually has nothing to do with polymorphism. To answer your question, two aspects of knowledge are needed.

1. Member function’s this pointer

First of all, to access the members of the class within the member function of the class, you need to access it through the this pointer (it can be omitted if the name does not conflict). When calling a member function through an object, the object itself will be passed through the this pointer Passed to member function. For example:

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
}

Why can I access the member a.get() of object a in the x function? Just through this this pointer. When calling a through a.get(), the compiler will assign the address of object a to the this pointer, where the type of the this pointer is A *const. Within the get() function, the statement return x; is actually equivalent to return this->x;, so we can access the member a.get() of the object a through x.

Similarly, why can a.set(10); assign the value of member a of object x to 10? Also through the this pointer. x = xx; is equivalent to this->x = xx;.

In the above two cases, since there is no ambiguity in the parsing of x, the this pointer can be omitted. However, what if I want to use the same variable name as the member set in the parameters of the member function x? Still distinguished by the this pointer. We can modify the definition of member function set as follows:

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

The this pointer here cannot be omitted, otherwise, there will be ambiguity when written as x = x;, and the compiler cannot resolve whether x is a parameter of a function or a member of an object.

2. constMember functions

Consider a situation. In the previous example, our object a is a non-constant object. What if we want to use class A to declare a constant object? For example

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

For built-in types, you can directly define a constant ci and use its value. For our own defined class A, we can also use the same method to define constants ca and obtain the value of member ca.get() of object a through x.

However, when using member functions to obtain the value of its data member x, we actually still access the member this through the x pointer. The problem is that at this time, the this pointer is not const A *const type, but A *const type. We know that the content of a constant cannot be accessed through a non-const pointer, that is,

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

So how to access member this through x pointer? We need to find a way to make the this pointer into a const A *const type. The way is to add the const keyword at the end of the class member function declaration, which means that the member function is const member function, and the this pointer within the function is a constant type. For example, we can overload the get() method:

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

At this time,

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

It will run normally.

Application

Specific to your question,

When I add const after the function declaration of the abstract base class, there will be no type incompatibility. Why is this?

In the store_file() function, its parameter img_file is a constant reference type. If you want to call a member function through a constant object, you need the this pointer of the member function of this object to also be a constant type.

When you add get_file_name() after the const function declaration of the abstract base class, the this pointer in this function changes from the Image_file *const type to the const Image_file *const type. At this time, return file_name + std::string(".gif"); The member file_name in is called through the this pointer of constant type. Thus the above requirements are met.

洪涛

const objects can only call const member functions

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template