复制构造函数

Posted 木鸟飞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了复制构造函数相关的知识,希望对你有一定的参考价值。

主要是想说复制构造函数的,但是偏偏问题就来了。所以还介绍了

passing \'const Student\' as \'this\' argument of \'int Student::getId()\' discards qualifiers [-fpermissive]

error:passing ‘const LineList<int>’ as ‘this’ argument of ‘void LineList<T>::Out(ostream&) [with T = int]’ discards qualifiers  

这个问题。

 

解决方案:来自博客:http://blog.csdn.net/rainkin1993/article/details/8034657

写的十分靠谱。

原文问题:

error:passing ‘const LineList<int>’ as ‘this’ argument of ‘void LineList<T>::Out(ostream&) [with T = int]’ discards qualifiers  

“意思是说  在一个加了const限定符的成员函数中,不能够调用 非const成员函数。

因为如果调用了非const成员函数,就违反了const成员函数不改变对象的规定。

error...discards qualifiers 的意思就是缺少限定符

因此,他的解决办法很简单了 ,只要将checkElements()函数申明改为  checkElements()const就行了

——rainkin1993 

换成自己的话再说一遍就是:

我们在拷贝构造函数中使用了(const student &st)一个student的对象,并且他是const的。所以要求对于在使用过程里面的st所要调用的函数也必须是const的。 

举例: 

正常情况下: 

student.h 中: 

int getId(void); 

student.cpp中: 

int student::getId(void){ 

return this->id; 

}

 

拷贝构造函数中: 

student::student(student &st){ 

this->id = st.getId(); 

}

 

上面这一套写法通过。 

 

修改: 

拷贝构造函数中:原来的st中的内容必然不能变化所以: 

student::student(const student &st){ 

this->id = st.getId(); 

//这样在QT中就会报discards qualifiers [-fpermissive]错误。 

解决方式: 

student.h 中: 

int getId(void)const; 

student.cpp中:

int student::getId(void)const{

return this->id;

}

这是这里面一个cosnt的用法,比起C语言来讲又多了一个点,就像extern一样有双重含义。

关于深浅拷贝:http://www.cnblogs.com/BlueTzar/articles/1223313.html

vs中实现的,因为在QT里面忘记了字符串复制的时候忘记进行初始化了,总之同样的代码貌似对于我来说,vs更好上手。QT有点儿看不懂它提示的错误。但是QT里面的“.”能自动帮我们解析。总之各有利弊吧。

下面是复制构造函数的例程:

student.h

#pragma once
class student
{
private:
    int id;
    char *name;
public:
    student();
    int getId(void) const ;
    void setId(int id);
    char *getName(void) const;
    void setName(const char *name);
    student(const student &st);
    ~student();
};

main.c

#include <iostream>
#include "student.h"
using namespace std;
int main(){
    student *s1 = new student;
    s1->setId(1);
    s1->setName("lifei");
    cout << s1->getId() << endl;
    cout << s1->getName() << endl;
    student *s2 = new student;
    s2 = s1;//浅拷贝
    cout << "s1\'s id is " << s1->getId() << " name is " << s1->getName() << endl;
    cout << "s2\'s id is " << s2->getId() << " name is " << s2->getName() << endl;
    s1->setName("letben");
    cout << "s1\'s id is " << s1->getId() << " name is " << s1->getName() << endl;
    cout << "s2\'s id is " << s2->getId() << " name is " << s2->getName() << endl;
    student *s3 = new student(*s1);//深拷贝
    s1->setName("qingwa");
    cout << "s1\'s id is " << s1->getId() << " name is " << s1->getName() << endl;
    cout << "s3\'s id is " << s3->getId() << " name is " << s3->getName() << endl;
    system("pause");
    return 0;
}

student.cpp

#include "student.h"
#include <string.h>
#include <iostream>
#pragma warning(disable:4996)
student::student()
{
}
student::~student()
{
    //func1:
    /*
    if (this->name != NULL){
        free(this->name);
    }*/
    //func2:
    if (this->name != NULL){
        delete []this->name;
    }
}
int student::getId(void) const {
    return this->id;
}
void student::setId(int id){
    this->id = id;
}
char *student::getName(void)const {
    return this->name;
}
void student::setName(const char *name){
    //std::cout << strlen(name) << std::endl;
    //这个不能完善!!!写这写着又变回C了。得赶紧到stl我猜。复制 再malloc是嘛。。。假装写一下吧
    //func1:
    //this->name = (char *)malloc(strlen(name) + 1);//感觉还是vs好一点儿,最起码知道哪里出了错误
    //strcpy(this->name, name);
    //func2:
    this->name = new char[strlen(name) + 1];
    strcpy(this->name, name);
}
student::student(const student &st){
    this->id = st.getId();//为了这句话可以通过 引用代表的当前对象调用的函数上需要加上const。
    this->setName(st.getName());
}

运行结果:

以上是关于复制构造函数的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段

为啥在我的代码中调用复制构造函数而不是移动构造函数?

防止 Proguard 删除片段的空构造函数

C#:如果一个类有两个构造函数,这些构造函数共享一些代码的最佳方式是啥? [复制]

无法解析片段中的 ViewModelProvider 构造?

为啥要避免片段中的非默认构造函数?