Programmers who do not like to use const are not good programmers-small talk C ++ (3)

Source: Internet
Author: User

[Mac 10.7.1 lion intel-based x64 gcc4.2.1 xcode4.2]

Q: Do the const keywords in C and C ++ have the same meanings?

A: They are not the same. In C, the const variable is unchangeable, and its core is variable. In C ++, the const variable is a constant. For example, a variable modified with const in C language cannot be used as the number of elements in an array that cannot be extended, but C ++ can.

Q: Will the const modification affect the overload function?

A: Yes.

Q: Why does the following code prompt function redefinition?

#include <iostream>using namespace std;int add(int a, int b){    return a + b;}int add(const int a, const int b){    return a + b;}int main (int argc, const char * argv[]){    return 0;}

Redefinition of 'add'

A: This is because although the const has an impact on function overloading, it is only valid for reference or pointer type of the form parameter. Because const int A allows receiving non-const type integers as parameters, this is the same as the form of the first add function. At that time, the compiler may not know which function the programmer wants to call.

Q: It's okay to change it to this form.

int add(int a, int b){    return a + b;}int add(const int &a, const int &b){    return a + b;}

A: This does not cause compilation errors. However, if you use the Add function, compilation errors may easily occur.

#include <iostream>using namespace std;#define COUT_ENDL(str)  std::cout << #str << " is " << (str) << std::endl;int add(int a, int b){    return a + b;}int add(const int &a, const int &b){    return a + b;}int main (int argc, const char * argv[]){    COUT_ENDL(add(1, 2))    return 0;}

Compilation prompt:

Call to 'add' is ambiguous

It can be seen that the compiler cannot tell which add function to call. Therefore, if you need to write code similar to the above Add code, think about how to remove one.

Q: Is there no solution?

A: Yes. You can change the form of the first add function. The changes are as follows:

int add(int &a, int &b){    return a + b;}int add(const int &a, const int &b){    return a + b;}

The following is a test of the call situation:

#include <iostream>using namespace std;#define COUT_ENDL(str)      std::cout << #str << " is " << (str) << std::endl;#define COUT_CALL_FUNC(str)  std::cout << "call func: " << __func__ << #str << std::endl;int add(int &a, int &b){    COUT_CALL_FUNC("add(int &a, int &b)")    return a + b;}int add(const int &a, const int &b){    COUT_CALL_FUNC("add(const int &a, const int &b)")    return a + b;}int main (int argc, const char * argv[]){    int i = 10, j = 20;    COUT_ENDL(add(1, 2))    COUT_ENDL(add(i, j))    return 0;}

The output is as follows:

add(1, 2) is call func: add"add(const int &a, const int &b)"3add(i, j) is call func: add"add(int &a, int &b)"30

We can see that two versions of the add function are called respectively.

Q: Since const can reflect the differences between two functions, can a function modified with const and a function without const be considered as a overload in a class?

A: Yes. The following code:

#include <iostream>using namespace std;#define COUT_ENDL(str)      std::cout << #str << " is " << (str) << std::endl;#define COUT_CALL_FUNC(str)  std::cout << "call func: " << __func__ << #str << std::endl;class Student{public:    Student(int age):_age(age) { }    ~Student(){ }    public:    int age() { return _age; }    int age() const { return _age; }    private:    int _age;};int main (int argc, const char * argv[]){    Student s(25);    COUT_ENDL(s.age())        return 0;}

Save as testforcpp. cpp, compile and generate testforcpp, and run OK.

Q: How do I know that two age functions in the student class are overload functions?

A: To ensure that two age functions can be seen in the symbol table, modify the Code as follows:

#include <iostream>using namespace std;#define COUT_ENDL(str)      std::cout << #str << " is " << (str) << std::endl;#define COUT_CALL_FUNC(str)  std::cout << "call func: " << __func__ << #str << std::endl;class Student{public:    Student(int age):_age(age) { }    ~Student(){ }    public:    int age() { return _age; }    int age() const { return _age; }    private:    int _age;};int main (int argc, const char * argv[]){    Student s(25);    COUT_ENDL(s.age())        const Student s1(22);    COUT_ENDL(s1.age())        return 0;}

Recompile and generate testforcpp.

Run the NM command to obtain the internal symbol table of the executable file that contains age:

It can be seen that there are actually two age-related functions, and we can guess that they are two age functions in the code. To confirm, debug the application, add a breakpoint to the two age function portals and run:

When the first age function is interrupted, run the disassemble command to compile the current function:

(gdb) disassembleDump of assembler code for function _ZN7Student3ageEv:0x0000000100000c70 <_ZN7Student3ageEv+0>:push   %rbp0x0000000100000c71 <_ZN7Student3ageEv+1>:mov    %rsp,%rbp0x0000000100000c74 <_ZN7Student3ageEv+4>:mov    %rdi,-0x8(%rbp)0x0000000100000c78 <_ZN7Student3ageEv+8>:mov    -0x8(%rbp),%rdi0x0000000100000c7c <_ZN7Student3ageEv+12>:mov    (%rdi),%eax0x0000000100000c7e <_ZN7Student3ageEv+14>:pop    %rbp0x0000000100000c7f <_ZN7Student3ageEv+15>:retq   End of assembler dump.(gdb) 

It can be seen that the function name is indeed _ zn7student3ageev (although the underline is missing, because the function name may be slightly different in different debuggers or executable files ).

Continue to run. The second age function entry is interrupted:

(gdb) disassembleDump of assembler code for function _ZNK7Student3ageEv:0x0000000100000c80 <_ZNK7Student3ageEv+0>:push   %rbp0x0000000100000c81 <_ZNK7Student3ageEv+1>:mov    %rsp,%rbp0x0000000100000c84 <_ZNK7Student3ageEv+4>:mov    %rdi,-0x8(%rbp)0x0000000100000c88 <_ZNK7Student3ageEv+8>:mov    -0x8(%rbp),%rdi0x0000000100000c8c <_ZNK7Student3ageEv+12>:mov    (%rdi),%eax0x0000000100000c8e <_ZNK7Student3ageEv+14>:pop    %rbp0x0000000100000c8f <_ZNK7Student3ageEv+15>:retq   End of assembler dump.(gdb) 

You can also confirm its function name.

Q: Why is it necessary to modify the formal parameters of the copy constructor of a class?

A: Yes. The following code:

#include <iostream>using namespace std;#define COUT_ENDL(str)      std::cout << #str << " is " << (str) << std::endl;class Student{public:    Student(int age):_age(age) { }    ~Student(){ }    Student(Student &s);    public:    int age() { return _age; }    int age() const { return _age; }    private:    int _age;};Student::Student(Student &s){    _age = s._age;}int main (int argc, const char * argv[]){    const Student s1(21);    Student s2(s1);    COUT_ENDL(s2.age())            return 0;}

The format parameter of the copy constructor of student is not modified by const. The compilation error occurs when the const object S1 is passed as the parameter to construct S2.

No matching constructor for initialization of 'Student'

The reason is that the const object S1 is an object that cannot be modified. The reference is used to input a function that can modify the form parameter. This may cause unexpected situations, so the compiler reports an error.

In short, the addition of the const keyword disrupted the original language, and the language must pay a new price for it. In some cases, it must be considered for const to achieve the integrity of the C ++ system.

Xichen

16:18:43

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.