《新标准C++程序设计》3.3-3.4(C++学习笔记7)
1、构造函数、析构函数和变量的生存期
构造函数在对象生成时会被调用,析构函数在对象消亡时会被调用。
程序示例分析:
(1)
#include<iostream>
using namespace std;
class Demo {
int id;
public:
Demo(int i) { //类型构造函数
id = i;
cout << "id=" << id << " constructed" << endl;
}
~Demo() { //析构函数
cout << "id=" << id << " destructed" << endl;
}
};
Demo d1(); //全局变量,在main之前初始化
void Func()
{
static Demo d2();//静态局部变量,func结束消亡
Demo d3();
cout << "func" << endl;
}
int main() {
Demo d4();
d4 = ;
cout << "main" << endl;
{ Demo d5(); //局部变量的作用域和生存期都只到离它最近的,且将其包含在内的那一对“{}”中的“}”为止
}
Func(); //引发析构函数
cout << "main ends" << endl;
return ;
}
输出结果:
id= constructed
id= constructed
id= constructed
id= destructed
main
id= constructed
id= destructed
id= constructed
id= constructed
func
id= destructed
main ends
id= destructed
id= destructed
id= destructed
(2)
#include <iostream>
using namespace std;
class CMyclass {
public:
CMyclass() {};
CMyclass( CMyclass & c)
{
cout << "copy constructor" << endl;
}
~CMyclass() { cout << "destructor" << endl; }
};
输出结果:
copy constructor
fun
destructor //参数消亡
test
copy constructor
destructor // 返回值临时对象消亡
destructor // 局部变量消亡
destructor // 全局变量消亡
2、复制构造函数在不同编译器中的表现
class A {
public:
int x;
A(int x_):x(x_)
{ cout << x << " constructor called" << endl; }
A(const A & a ) { //本例中dev需要此const其他编译器不要
x = + a.x;
cout << "copy called" << endl;
}
~A() { cout << x << " destructor called" << endl; }
};
A f( ){ A b(); return b; }
int main( ){
A a();
a = f();
return ;
}
Visual Studio输出结果:
constructor called
constructor called
copy called
destructor called
destructor called
destructor called
Dev C++输出结果:
constructor called
constructor called
destructor called
destructor called
说明Dev出于优化目的并未生成返回值临时对象。 VS无此问题
3、静态成员变量和静态成员函数
(1)概念
静态成员:在说明前面加了static关键字的成员。
class CRectangle
{
private:
int w, h;
static int nTotalArea; //静态成员变量
static int nTotalNumber; //静态成员变量
public:
CRectangle(int w_, int h_);
~CRectangle();
static void PrintTotal(); //静态成员函数
};
普通成员变量每个对象有各自的一份,而静态成员变量一共就一份,为所有对象共享。普通成员函数必须具体作用于某个对象,而静态成员函数并不具体作用于某个对象。因此静态成员不需要通过对象就能访问。
静态成员变量本质上是全局变量,哪怕一个对象都不存在,类的静态成员变量也存在。静态成员函数本质上是全局函数。设置静态成员这种机制的目的是将和某些类紧密相关的全局变 量和函数写到类里面,看上去像一个整体,易于维护和理解。
sizeof 运算符不会计算静态成员变量。
class CMyclass {
int n;
static int s;
};
sizeof( CMyclass ) 等于 4
(2)如何访问静态成员
①类名::成员名
CRectangle::PrintTotal();
②对象名.成员名
CRectangle r;
r.PrintTotal();
③指针->成员名
CRectangle * p = &r;
p->PrintTotal();
④引用.成员名
CRectangle & ref = r;
int n = ref.nTotalNumber;
(3)静态成员示例
考虑一个需要随时知道矩形总数和总面积的图形处理程序可以用全局变量来记录总数和总面积用静态成员将这两个变量封装进类中,就更容易理解和维护
#include<iostream>
using namespace std;
class CRectangle
{
private:
int w, h;
static int nTotalArea;
static int nTotalNumber;
public:
CRectangle(int w_, int h_);
~CRectangle();
static void PrintTotal();
};
CRectangle::CRectangle(int w_, int h_)
{
w = w_;
h = h_;
nTotalNumber++;
nTotalArea += w * h;
}
CRectangle::~CRectangle()
{
nTotalNumber--;
nTotalArea -= w * h;
}
void CRectangle::PrintTotal()
{
cout << nTotalNumber << "," << nTotalArea << endl;
}
int CRectangle::nTotalNumber = ;
int CRectangle::nTotalArea = ;
// 必须在定义类的文件中对静态成员变量进行一次说明
//或初始化。否则编译能通过,链接不能通过。
int main()
{
CRectangle r1(, ), r2(, );
//cout << CRectangle::nTotalNumber; // Wrong , 私有
CRectangle::PrintTotal();
r1.PrintTotal();
return ;
}
输出结果:
,
,
此CRectangle类写法, 有何缺陷?
在使用CRectangle类时,有时会调用复制构造函数生成临时的隐藏的CRectangle对象
调用一个以CRectangle类对象作为参数的函数时
调用一个以CRectangle类对象作为返回值的函数时
临时对象在消亡时会调用析构函数,减少nTotalNumber 和 nTotalArea的值,可是这些临时对象在生成时却没有增加 nTotalNumber 和 nTotalArea的值。
解决办法:为CRectangle类写一个复制构造函数。
CRectangle :: CRectangle(CRectangle & r )
{
w = r.w; h = r.h;
nTotalNumber ++;
nTotalArea += w * h;
}
(4)为什么在静态成员函数中,不能访问非静态成员变量, 也不能调用非静态成员函数?
void CRectangle::PrintTotal()
{
cout << w << "," << nTotalNumber << "," <<nTotalArea << endl; //wrong
}
CRetangle::PrintTotal(); //解释不通,w 到底是属于那个对象的?
《新标准C++程序设计》3.3-3.4(C++学习笔记7)的更多相关文章
- 《新标准C++程序设计》4.5(C++学习笔记15)
实例:长度可变的整型数组类 int main() { //要编写可变长整型数组类,使之能如下使用: CArray a; //开始里的数组是空的 ; i < ; ++i) a.push_back( ...
- 《新标准C++程序设计》4.6(C++学习笔记16)
重载流插入运算符和流提取运算符 流插入运算符:“<<” 流提取运算符:“>>” cout 是在 iostream 中定义的,ostream 类的对象. “<<” 能 ...
- 《新标准C++程序设计》4.4(C++学习笔记14)
运算符重载为友元函数 一般情况下,将运算符重载为类的成员函数,是较好的选择. 但有时,重载为成员函数不能满足使用要求,重载为普通函数,又不能访问类的私有成员,所以需要将运算符重载为友元. class ...
- 《新标准C++程序设计》4.1(C++学习笔记12)
运算符重载的概念和原理 一.运算符重载的需求 C++预定义的“+.-. * ./.%. ^ .&.~.!.|. = .<< >>.!= ”等运算符,只能用于基本数据类型 ...
- 《新标准C++程序设计》3.8(C++学习笔记10)
友元 友元分为友元函数和友元类两种. 一.友元函数 在定义一个类的时候,可以把一些函数(包括全局函数和其它类的成员函数)声明为“友元”,这样那些函数就成为该类的友元函数,在友元函数内部就可以访问该类对 ...
- 《新标准C++程序设计》3.5(C++学习笔记8)
常量对象和常量成员函数 一.常量对象 如果希望某个对象的值初始化后就再也不被改变,则定义该对象时可以在前面加const关键字,使之成为常量对象. class CDemo { private: int ...
- 正确处理类的复合关系------新标准c++程序设计
假设要编写一个小区养狗管理程序,该程序需要一个“主人”类,还需要一个“狗”类.狗是有主人的,主人也有狗.假定狗只有一个主人,但一个主人可以有最多10条狗.该如何处理“主人”类和“狗”类的关系呢?下面是 ...
- 在成员函数中调用虚函数(关于多态的注意事项)------新标准c++程序设计
类的成员函数之间可以互相调用.在成员函数(静态成员函数.构造函数和析构函数除外)中调用其他虚成员函数的语句是多态的.例如: #include<iostream> using namespa ...
- 多态实现的原理------新标准c++程序设计
“多态”的关键在于通过基类指针或引用调用一个虚函数时,编译时不确定到底调用的是基类还是派生类的函数,运行时才确定.例子: #include<iostream> using namespac ...
- 多态的作用-游戏编程展示------新标准c++程序设计
游戏软件的开发最能体现面向对象设计方法的优势.游戏中的人物.道具.建筑物.场景等都是很直观的对象,游戏运行的过程就是这些对象相互作用的过程.每个对象都有自己的属性和方法,不同对象也可能有共同的属性和方 ...
随机推荐
- jetson nano 安装 snowboy 遇到的问题及处理
Snowboy 是 KITT.AI 开发的一个高度可定制的热词检测引擎,当笔者的 jetson nano 加上话筒后,就立马尝试安装,但在安装过程中却发生了错误,所以把处理方式记录了下来以作备忘. 首 ...
- python 通过UDP传输文件
使用一个简单的python脚本将一个本地文件以码流的形式,通过UDP协议发送到对端: import socket import os import stat import struct MAX_P ...
- idea2019 3.3最新版本破解安装教程
直接给上神秘地址得了:(应该都可以破解) https://www.jianshu.com/p/c7bdc5819d31
- mabatisplus-update
/** * <p> * 根据 whereEntity 条件,更新记录 * </p> * * @param entity 实体对象 (set 条件值,不能为 null) * @p ...
- 在centos7中安装MySQL5.7
1.下载mysql源安装包 wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm 2.安装mysql源 yu ...
- 多进程之multiprocessing模块、守护进程、互斥锁
目录 1. multiprocessing 模块介绍 2. Process类的介绍 3. Process类的使用 4. 守护进程 5. 进程同步(锁) 1. multiprocessing 模块介绍 ...
- 【转载】如何快速转载CSDN中的博客
前言 对于喜欢逛CSDN的人来说,看别人的博客确实能够对自己有不小的提高,有时候看到特别好的博客想转载下载,但是不能一个字一个字的敲了,这时候我们就想快速转载别人的博客,把别人的博客移到自己的空间 ...
- linux动态库(.so)和静态库(.a)的区别
静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库.编译之后程序文件大,但加载快,隔离性也好. 动态库在程序编译时并不会被连接到目标代码中,而是在程序运行时才被载入,因此在程序运行时 ...
- 标准模板库中的栈(stack)
////C++数据结构与算法(第4版) Adam Drozdek 著 徐丹 吴伟敏<<清华大学出版社>> STL中的通用栈类实现为容器适配器:使用以指定方式运行的容器.栈容 ...
- TP-Link TL-WR841N v14 CVE-2019-17147 缓冲区溢出漏洞分析笔记v2018.12.31
0x00 背景 Httpd服务中的缓冲区溢出漏洞 复现参考文章https://www.4hou.com/posts/gQG9 Binwalk -Me 解压缩 File ./bin/busybox文件类 ...