1.拷贝构造

//拷贝构造的规则,有两种方式实现初始化。

//1、一个是通过在后面:a(x),b(y)的方式实现初始化。

//2、第二种初始化的方式是直接在构造方法里面实现初始化。

案例如下:

#include<iostream>//如果声明已经定义,边不会生成
class classA
{
private:int a;int b;
public://拷贝构造的规则,有两种方式实现初始化//1、一个是通过在后面:a(x),b(y)的方式实现初始化//2、第二种初始化的方式是直接在构造方法里面实现初始化classA(int x,int y)//:a(x),b(y){a = x;b = y;}void print(){std::cout << a << " " << b << std::endl;}
};void main()
{classA class1(10,100);//编译器会默认生成默认的构造函数classA class2(class1);//编译器会生成默认的拷贝构造函数class1.print();//默认的拷贝构造函数,说明可以通过类的方式实现浅拷贝class2.print();std::cin.get();
}

2.深度拷贝,使用深度拷贝的时候要将分配内存,这是其中的关键点。

#define  _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<string>
class string
{
public:char *p;int length;string(int num, char *str){//获取长度,分配内存,拷贝内容length = num;p = new char[length]; //深度拷贝的时候,要分配内存memset(p, 0, length);//strcpy(p, str);}string(const string & string1){this->p = new char[string1.length];this->length = string1.length;//将开辟的内存中的内容赋值为0memset(this->p, 0, this->length);strcpy(this->p, string1.p);}~string(){delete[] p;//删除的时候要带上[]}
};
void main()
{string *pstr1 = new string(10, "hello");std::cout << pstr1->p << std::endl;string *pstr2 = new string(*pstr1);delete pstr1;std::cout << pstr2->p << std::endl;std::cin.get();
}

上面的运行结果是:

void main()
{string str1(10,"hello");std::cout << str1.p << std::endl;string str2(str1); //这里说明可以通过std::cout << str2.p << std::endl;std::cin.get();
}

运行结果如下:

3.关于delete和default相关的操作

A:delete可以禁用默认生成的函数,禁用构造可以无法实例化,禁用拷贝构造,可以实现禁止别人拷贝你。

B:default的作用是让函数默认存在。

myclassA::myclassA(void);   //尝试引用已删除的函数
myclassA() = delete;        //默认删除构造函数,无法实例化
myclassA(const myclassA &) = delete;  //拷贝构造函数
myclassA(const myclassA &) = default;~myclassA();void main()
{//myclassA myclassa1;//myclassA myclassa2(myclassa1);//myclassA myclassa3 = myclassa1;   //重载了=,根据类型//myclassA a1;
}

4.explicit.cpp

#include <iostream>
#include <array>class  classobj
{
public:int num;
public://使用有参构造,使用explicitexplicit classobj(int data){this->num = data;std::cout << "被构造" << num << std::endl;}~classobj(){std::cout << "被销毁" << num << std::endl;}
protected:
private:
};void main()
{//C 语言风格的数组,构造一个数组,销毁一个数组classobj obj(0);//单独独有构造函数//C语言风格数组构造方式classobj objx[3] = { classobj(1), classobj(2), classobj(3) };classobj (*ppobjA)[3] = &objx; //指向数组的指针classobj *pobj(new classobj(4));classobj * ppobj[3];//数组,每一个元素都是指针ppobj[0] = new classobj(5);ppobj[1] = new classobj(6);ppobj[2] = new classobj(7);std::cin.get();
}

运行结果如下:

5.类的赋初值

第一种方式:  在构造函数后面通过加上  :变量名(变量值)

第二种方式:在构造函数,函数体里面写上   变量名=变量值;

第三种方式:类名对象名=变量值

#include <iostream>
#include <array>class  classobj
{
public:int num;
public://使用有参构造,使用explicitclassobj(int data){this->num = data;std::cout << "被构造" << num << std::endl;}~classobj(){std::cout << "被销毁" << num << std::endl;}
protected:
private:
};void main()
{classobj num = 5;//赋值号,类型转换num = 6;         //说明类的初始化可以通过等号的方式赋值classobj data(7);classobj obj(8); //创建对象必须合适的构造函数//C++风格数组的作用classobj *p = new classobj(9);std::array<classobj, 2> myarray = { obj, *p };std::cin.get();
}

运行结果是:

赋值案例2:

#include <iostream>class myclass
{
public:int num;
public:myclass():num(4)//初始化第一种方式{//num = 10; //第二种方式}myclass(int data)  //构造函数可以重载{std::cout << "class create by data: " << data << std::endl;num = data;}~myclass(){std::cout << "class delete";}
};void run()
{myclass myclass1(10);myclass myclass2 = 102;myclass *p = new myclass(103);myclass *p2(new myclass(104));std::cout << (*p).num << std::endl;//std::cout << myclass1.num << std::endl;
};void main()
{run();std::cin.get();
}

运行结果如下:

6.构造函数与析构函数

A:系统自动生成了构造函数与析构函数

B:被包含的,最先调用构造,最后调用析构

C:包含别人的,最后调用构造,最先调用析构

案例说明:

#include <iostream>//系统自动给你生成了构造函数与析构函数
//被包含的,最先分配,最后释放(这里是调用析构不是释放内存)
//包含别人的,最后分配,最先释放(这里是调用析构不是释放内存)class fushu
{
public:fushu();~fushu();
};fushu::fushu()
{std::cout << "fushu构建" << std::endl;
}fushu::~fushu()
{std::cout << "fushu销毁" << std::endl;
}class math
{
public:fushu fushu1;//一个类调用另外一个类math(){std::cout << "math构建" << std::endl;}~math(){std::cout << "math销毁" << std::endl;}
};void go()
{math math1;
}void main()
{go();std::cin.get();
}

运行结果截图:

分析,上面的math类调用fushu这个类,这个结果说明了A,B,C.

7.成员函数和内联函数

A:内联函数一般在头文件中。

编写头文件:

#pragma once
#include <iostream>
class fushu
{
public:int x;int y;
public:fushu();~fushu();void show();//显示内联inline void showall(int x, int y);//编译器优化,默认隐式内联void setxy(int x, int y);void show(int x,int y);
};//内联函数原则上放在头文件,并且在实现内联函数的时候,去掉inline标识符
//内联函数需要展开,(VS2013是要求放在头文件的)
void fushu::showall(int x, int y)
{std::cout << "头文件中内联函数showall:this->x = " <<(this->x = x) << "this->y =" <<(this->y = y) << std::endl;
}

头文件中的实现类

#include "fushu.h"
//::这个符号卡面必须是类或者命名空间fushu::fushu()
{std::cout << "对象被创建" << std::endl;
}fushu::~fushu()
{std::cout << "对象被销毁" << std::endl;
}
//类调用成员函数,需要明确那个类的对象调用void fushu::show()
{std::cout << "show" << std::endl;
}void   fushu::setxy(int x, int y)//编译器优化,默认隐式内联
{this->x = x;this->y = y;std::cout << "实现类中setxy:(this->x)= "<<(this->x)<< " (this->y)=" << (this->y) << std::endl;
}void  fushu::show(int x, int y)
{std::cout << "实现类中show:(this->x)= " << (this->x) << " (this->y)=" << (this->y) << std::endl;
}

调用函数:

#include<iostream>
#include "fushu.h"void stackrun()
{fushu fushu1;//对象在栈上fushu1.show();
}void heaprun()
{fushu *pfushu = new fushu;//对象在堆上pfushu->show();pfushu->showall(10, 9);pfushu->setxy(19, 29);pfushu->show(1, 2);//内部成员函数重载,函数指针,明确了参数delete pfushu;
}void main()
{heaprun();std::cin.get();
}

7.关于内存

#include <iostream>class myclass
{
public:int num;int data;int *p;const int coint;//常量必须在构造函数中初始化int & myint;    //引用必须初始化,在构造函数中初始化static int shu; //声明,在外部进行初始化static const int dashu;
public:static void go(){}void run(){}//常量,引用,必须重载构造函数初始化myclass(int a, int b) :myint(a), coint(b){//引用就是共用地址,常量新开辟备份机制std::cout << &a << "  " << &b << std::endl;std::cout << &myint << "  " << &coint << std::endl;const int *p = &coint;//地址std::cout << *p << "   " << coint << std::endl;int *px = const_cast<int *>(p);//去掉const转换*px = 12;std::cout << coint << "  " << *px << std::endl;}~myclass(){}
};//对于静态的变量要在类外面初始化
int myclass::shu = 0;
//对于静态的变量要在类外面初始化
const int myclass::dashu = 20;void main()
{const int *px = &(myclass::dashu);std::cout << px << std::endl;int *p = const_cast<int *>(px);//静态常量区可以访问,不可以修改,所以下面的方式是错误的//*p = 123;std::cout << *px << "  " << *p << "   " << myclass::dashu;std::cin.get();
}

运行结果是:

8.关于默认参数

#include<iostream>class goodclass
{
public:int num = 1;//默认初始化的值,C++11特定const int data = 90;//const,这种方式初始化就不需要写构造函数了
public:static void show(goodclass good1){std::cout << good1.num << "  " << good1.data << std::endl;}
};
//类中的const默认还是可以修改,与C语言const一致
void main()
{goodclass good1;goodclass::show(good1);const int *px = &(good1.data); //这里表示指向常量的值std::cout << px << std::endl;int *p = const_cast<int *> (px);//取消常量属性*p = 123;std::cout << *px << "  " << *p << "   " << good1.data << std::endl;goodclass::show(good1);std::cin.get();
}

运行结果:

9.在类里面定义一个静态变量,实现计数并限制QT中弹出窗体,建立QMainWindow的QT项目。(如果想让QT支持C++11的语法,需要在QT项目的pro文件中加入:CONFIG += c++11,可以再最后面附加上)其中main.cpp的代码是:

#include "mainwindow.h"
#include <QApplication>
#include <QDebug>   //这个头文件要加上
class mywindow
{public:mainwindow *p;   //这里的mainwidow标识的是窗体类static int num;  //所有类都可以访问静态区mywindow(){if(num > 2)//静态类成员进行成员{}else{num++;qDebug()<<"create";this->p = new mainwindow;//实例化一个对象this->p->show();//让这个窗体显示}}~mywindow(){qDebug() << "delete";delete this->p;}
};//对静态变量赋初值
int mywindow::num = 0;void run()
{mywindow my1;//栈上
}int main(int argc, char *argv[])
{QApplication a(argc, argv);mywindow *pwindow = new mywindow;qDebug() << mywindow::num;//通过这行打印出次数//下面是低吗快{mywindow  *pwindow=new mywindow;qDebug() << pwindow->num;}{mywindow  *pwindow=new mywindow;qDebug() << pwindow->num;}{mywindow  *pwindow=new mywindow;qDebug() << pwindow->num;}return a.exec();
}

10.静态函数和普通函数

#include "mainwindow.h"
#include <QApplication>
#include <stdlib.h>
#include <QDebug>class mywindow
{
public:MainWindow w;public:static void run()  //因为加了static,所以不用实例化就可以用。{system("calc");}void notepad(){system("notepad");}
};class mywindowW
{
public:MainWindow w;  //继承int #
public:mywindowW(int data):num(data)  //给data初始化{}
};int main(int argc, char *argv[])
{QApplication a(argc, argv);mywindow mywindow1;mywindow1.w.show();mywindow1.run();     //第一种调用方式mywindow1.notepad();//mywindow1::notepad();//这种方式不可以直接地调用mywindow::run();//不需要实例化的情况就可以调用return a.exec();
}

运行结果是弹出计算器和记事本。

11.函数默认参数,对于给含有默认参数的函数赋值的时候,参数的赋值将从左往右赋值给函数中的参数。

案例如下:

#include "mainwindow.h"
#include <QApplication>class mywindow
{
public:MainWindow w;MainWindow *p;//如果在调用的时候只传递一个参数的时候,这个参数赋值给了str1void settitle(char *str1="XYZ",char *str2="THG"){w.setWindowTitle(str1);p->setWindowTitle(str2);}
};int main(int argc, char *argv[])
{QApplication a(argc, argv);mywindow my1;my1.p=new MainWindow;my1.w.show();my1.p->show();//传递参数的时候,从左往右填充,比如下面的AHNJ将赋值给*str1//可以只传递一个参数,也可以传递两个参数my1.settitle("AHNJ");return a.exec();
}

运行结果如下:

12.加了const之后函数和没有加const变量的函数的区别:

新建QT项目,编写代码:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECT//下面是新添加的
public:int x;int y;mutable int z;//不受const成员函数的约束public:explicit MainWindow(QWidget *parent = 0);~MainWindow();void resetxy();//没有const属性,可以修改成员变量void showxy() const;  //const,不可以修改一般的成员变量private:Ui::MainWindow *ui;
};#endif // MAINWINDOW_H
编写MainWindow的实现
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::resetxy()
{this->x = 800;this->y = 600;resize(this->x,this->y);
}void MainWindow::showxy() const
{//因为是加了const,所以不再可以调用成员变量//this->x = 10;//因为没有加上mutable,所以不可以调用//this->y = 100;this->z = 1000;
}
调用main函数
#include "mainwindow.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;//重置窗口大小w.resetxy();w.show();return a.exec();
}

13.关于友元函数,案例如下(不用修改QT的头文件和头文件的实现类):

#include "mainwindow.h"
#include <QApplication>//友元函数可以访问类中的私有变量,还可以访问私有函数
//友元函数声明的时候要有friend,定义的时候不需要friend了
//定义友元的时候也可以在内的内部
class mywindow
{MainWindow *p;void go(){system("notepad");}//声明一个友元函数void  friend showwindow(mywindow * pwin);
};//实现一个友元函数
void showwindow(mywindow *pwin)
{pwin->p=new MainWindow;pwin->p->show();pwin->go();
}int main(int argc, char *argv[])
{QApplication a(argc, argv);mywindow my1;// my1.p;showwindow(&my1);return a.exec();
}

14.友元类,当指向了一个指针的时候一定要初始化。否则将出现错误,下面的函数任然是main.cpp中的内容。

#include "mainwindow.h"
#include <QApplication>//被友元
class window
{MainWindow *p;void settitle(){this->p->setWindowTitle("1234");}friend class opwindow;//友元类
};class opwindow
{
private:window pwin; //类的变量,指针可以访问类的所有私有成员与函数window *ppwin;//指针必须初始化,必须分配内存public:void init(){//不初始化就是野指针,所以这里一定要初始化,不然会报错ppwin = new window;ppwin->p = new MainWindow();ppwin->p->show();}void setstr(){ppwin->settitle();}
};int main(int argc, char *argv[])
{QApplication a(argc, argv);opwindow opwindow1;opwindow1.init();opwindow1.setstr();//语法return a.exec();
}

友元类案例2

头文件QT项目:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);//重载MainWindow(const MainWindow & w){MainWindow(0);}~MainWindow();private:Ui::MainWindow *ui;//友元类friend class window;
};#endif // MAINWINDOW_Hmain.cpp
#include "mainwindow.h"
#include <QApplication>class window
{
public:MainWindow w;MainWindow *p;
};int main(int argc, char *argv[])
{QApplication a(argc, argv);window window1;window1.w.show();window1.p = new MainWindow(window1.w);window1.p->show();return a.exec();
}

拷贝构造,深度拷贝,关于delete和default相关的操作,explicit,类赋初值,构造函数和析构函数,成员函数和内联函数,关于内存存储,默认参数,静态函数和普通函数,const函数,友元相关推荐

  1. 侯捷-C++面向对象高级开发(三大函数:拷贝构造,拷贝赋值,析构)

    侯捷-C++面向对象高级开发(三大函数:拷贝构造,拷贝赋值,析构) 三大函数:拷贝构造,拷贝赋值,析构 第一个是拷贝构造,第二个是拷贝赋值 编译器有一套默认的东西实现这俩东西,可用到complex的实 ...

  2. C++之Big Three:拷贝构造、拷贝赋值、析构函数探究

    涉及到本文所讲知识点的博文: C++之析构函数探究 C++之常引用和浅拷贝探究 C++之一个函数链的简单例子(分文件实现) C++之Big Three:拷贝构造.拷贝赋值.析构函数探究 C++之操作符 ...

  3. C++——构造函数(拷贝构造,拷贝复制),析构函数,操作符重载

    C++--构造函数(拷贝构造,拷贝复制),析构函数,操作符重载 构造函数与析构函数:: 涉及构造函数还可以看这篇文章C++搞懂深拷贝初始化=与赋值=的区别 1.声明和定义构造函数和析构函数 构造函数在 ...

  4. C++网易云课堂开发工程师-拷贝构造,拷贝复制,析构函数

    1.带有指针的Class,Class with pointer member 当类内带指针,一定自己写出拷贝构造函数. String s1(); String s2("hello" ...

  5. C++之拷贝构造、拷贝赋值

    拷贝构造 class Stu{public:int no;string name;int age; public:Stu(int no=10086, string name="jin&quo ...

  6. 【C++11智能指针】shared_ptr的初始化、拷贝构造和拷贝赋值、移动构造和移动赋值

    文章目录 1.智能指针概述 2.shared_ptr的初始化 2.1 shared_ptr和new结合使用(直接初始化) 2.2 make_shared函数 3.shared_ptr的拷贝构造和拷贝赋 ...

  7. 对普通函数、宏函数、内联函数的作用机制的探索

    这次我们来分析的是C/C++程序员经常遇到的问题,如何在普通函数.宏函数.内联函数之间做取舍,其实它们三者之间并没有什么绝对的你好我差的说法,只要掌握了三者的作用机制的话,结合实际情况一般都能做出正确 ...

  8. 类的成员函数与内联以及静态成员

    一.类的成员函数与内联 在类内定义的所有函数都自动称为内联函数.如果在类内声明,在类外定义,也可以定义为内联函数.在定义函数时添加inline限定符.. (1)此外,内联函数一定要和函数定义在一起,否 ...

  9. inline函数_inline内联函数

    C++中的inline用法 - Boblim - 博客园​www.cnblogs.com 1.引入inline的原因 为了解决一些频繁调用但代码量很小的函数引起的大量消耗栈空间(内存)的问题 栈空间 ...

最新文章

  1. 骄阳似火 细数史上数据中心火灾 如何才能重蹈覆辙?
  2. 仿照支付宝账单界面--listview分组显示 用来做!发!财树充值交易明细
  3. 限时秒杀┃秒杀90%的玩具,让孩子爱上科学的彩虹实验2来了!
  4. selenium定位输入框_[Selenium 粗浅笔记] 用Selenium填写表单
  5. XenApp_XenDesktop_7.6实战篇之十二:组策略配置
  6. Linux+varnish安装配置
  7. 吴恩达机器学习(十六)机器学习流水线、上限分析
  8. postman压力测试_如何用Postman简单做接口自动化
  9. MyEclipse持续性开发教程:用JPA和Spring管理数据(三)
  10. Windows软件路由器运用实例之OSPF配置
  11. matlab版K均值聚类
  12. 计算机应用与篮球有关的文章,浅析计算机技术应用对高校篮球教学的作用与影响...
  13. web前端网页界面/css 仿微软官网界面
  14. 写一个自己的javascript库
  15. ie8打不开java项目_IE8点击打开没反应,尝试多种方法始终打不开
  16. 3D游戏场景模型制作的细节与技巧
  17. Cat.1、Cat.4、4G之间的区别
  18. 字节跳动最常问的前端面试题:Node.js 基础
  19. 详细讲解Html语言的书,HTML语言基础讲解.ppt
  20. 移动团购模式盘点及挑战分析

热门文章

  1. python matplotlib 绘图
  2. leetcode 分饼干 贪心算法python
  3. VTK:细胞中心演示用法实战
  4. wxWidgets:在 Unix (GTK+) 下打印
  5. wxWidgets:缓冲区类
  6. boost::tti模块测试函数模板
  7. boost::range模块heap算法相关的测试程序
  8. boost::parameter::template_keyword相关的测试程序
  9. boost::mp11::mp_count_if_q相关用法的测试程序
  10. boost::log模块实现如何同时对多个文件执行日志记录的测试程序