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;
//将开辟的内存中的内容赋值为0
memset(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:
//使用有參构造,使用explicit
explicit 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:
//使用有參构造,使用explicit
classobj(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();
}

执行结果例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdG90b3R1enVvcXVhbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

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();
}

执行结果截图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdG90b3R1enVvcXVhbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

分析,上面的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();
}

执行结果是:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdG90b3R1enVvcXVhbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

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();
}




watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdG90b3R1enVvcXVhbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

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; //假设在调用的时候仅仅传递一个參数的时候,这个參数赋值给了str1
void 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_OBJECT public:
explicit MainWindow(QWidget *parent = 0);
//重载
MainWindow(const MainWindow & w)
{
MainWindow(0);
} ~MainWindow(); private:
Ui::MainWindow *ui;
//友元类
friend class window;
}; #endif // MAINWINDOW_H main.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. const引用和函数占位参数遇上默认参数以及内联函数

    1.const引用: 但是加上const之后是可以的,const int &a=100;就不会报错了. 2.函数占位参数: 如果给最后的占位参数加上默认值: 3.内联函数 内联只是对编译器发起 ...

  2. 函数新特性、内联函数、const详解

    一.函数回顾与后置返回类型 函数定义中,形参如果在函数体内用不到的话,则可以不给形参变量名字,只给其类型. 函数声明时,可以只有形参类型,没有形参名 把函数返回类型放到函数名字之前,这种写法,叫前置返 ...

  3. C++初阶(命名空间+缺省参数+const总结+引用总结+内联函数+auto关键字)

    命名空间 概述 在C/C++中,变量.函数和后面要学到的类都是大量存在的,这些变量.函数和类的名称将都存在于全局作用域中,可能会导致很多冲突.使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲 ...

  4. 位运算+引用+const+new/delete+内联函数、函数重载、函数缺省参数

    update 2014-05-17 一.位运算 应用: 1.判断某一位是否为1 2.只改变其中某一位,而保持其它位都不变 位运算操作: 1.& 按位与(双目): 将某变量中的某些位(与0位与) ...

  5. 为什么内联函数,构造函数,静态成员函数不能为virtual函数

    http://blog.csdn.net/freeboy1015/article/details/7635012 为什么内联函数,构造函数,静态成员函数不能为virtual函数? 1> 内联函数 ...

  6. c++虚函数和内联构造函数

    创建一个含有虚函数的对象时, 编译器会实现 "初始化其VPTR以指向相应的VTABLE" 这个操作 ,而实现这个操作是通过 "插入隐藏代码至构造函数中" 故此时 ...

  7. 预处理、const、static与sizeof-为什么不把所有的函数都定义成内联函数

    1:内联是以代码膨胀(复制)为代价的,仅仅省去了函数调用的开销,从而提高函数的执行效率.如果执行函数体内代码的时间相比于函数调用的开销较大,那么效率的收获会很小.另一方面,每一处内联函数的调用都要复制 ...

  8. 20140808 const和define区别 内联函数(inline) 栈和堆的地址分配 栈帧

    1.const和define区别 const有数据类型(不能改变的变量),define只是简单的字符串替换,没有数据类型. C++程序用const完全取代 define. const还可以类成员函数为 ...

  9. 预处理、const、static、sizeof-说明内联函数使用的场合

    1:首先使用inline函数可以完全取代表达式形式的宏定义. 内联函数在C++类中的应用最广的应该是用来定义存取函数.我们定义的类中一般会把数据成员定义成私有的或者保护的,这样,外界就不能直接读写我们 ...

随机推荐

  1. 对于Netty的十一个疑问(转)

    [说明]本文原载于码农 IO(manong.io)官方微信 developerWorks,转载.引用请注明出处及作者. 1.Netty 是什么? Netty 是一个基于 JAVA NIO 类库的异步通 ...

  2. hdu3790最短路径问题

    题意是这种,给你一个无向图, 每条边有距离和花费, 假设从第一个点到末点的最短路不唯一, 则输出最短路长度以及最少的花费. 否则输出长度和花费即可. 用传说中的链式向前星优化了一下边的存储, 写了个s ...

  3. C#托付和事件

    C#托付.我看了非常长时间的资料和帖子, 曾经对托付的理解就是托付事实上就是将一个方法作为參数传递给第一个方法. 如今对托付的认识则变了一些的,托付能够实现: 1.在两个不能直接调用的方法之间做为桥梁 ...

  4. 使用C/C++编译预处理时须要注意的问题

    1.宏定义不是C/C++语句,不须要使用语句结束符":",否则它也被看做宏体的一部分. 2.不要在引用宏定义的參数列表中使用增量和减量运算符,否则将导致变量的多次求值.比如: #d ...

  5. SQL Server安全性专题一:简介

    原文:SQL Server安全性专题一:简介 一. 安全威胁与法则 1. 安全定义 2. 安全威胁 3. 安全法则 安全定义: 在SQLServer环境中,安全性可以认为是[数据保护].包括:  数 ...

  6. unity3D实际的原始视频游戏开发系列讲座10它《战斗:外来入侵》在第一季度游戏开发

    解说文件夹 <保卫战:异形入侵>游戏开发 第一讲   游戏演示和资源的介绍 第二讲  "异形"怪物的实现 第三讲  "异形"怪物生命值的体现 第四讲 ...

  7. 五通信算法:五种编码增益比较matlab模拟

    1. 卷积编码增益性能.BER 信道环境:AWGN 信噪比SNR :0:0.1:6 MATALB仿真架构:源比特 +卷积码 +BPSK +AWGN +Viterbi +BER 说明:卷积编码,不同的R ...

  8. Log4jdbc demo

    package log4jdbc; import java.sql.Connection; import java.sql.PreparedStatement; import org.junit.Te ...

  9. JS数组学习笔记

    原文:JS数组学习笔记 最近在备课数组,发现很多ES5的方法平时很少用到.细节比较多,自己做了大量例子和整理,希望对大家了解JavaScript中的Array有所帮助. 概念 数组是值的有序集合.每个 ...

  10. leetcode 之 Unique Paths

    Unique Paths A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagra ...