c++学习笔记之类

简介: 预处理器封套:#ifndef XXX_H#define XXX_H...class xxx{...}...#endif复制代码如果没有文件包含此头文件,XXX_H被定义并包含这个头文件;如果已经包含,则不再定义和包含。为了防止多次包含同一个头文件,尤其包含套包含的时候。注意命名要大写和下划线。

1、预处理器封套:


#ifndef XXX_H
#define XXX_H
...
class xxx{
...
}
...
#endif
复制代码


如果没有文件包含此头文件,XXX_H被定义并包含这个头文件;如果已经包含,则不再定义和包含。

为了防止多次包含同一个头文件,尤其包含套包含的时候。注意命名要大写和下划线。


2、对象的sizeof


sizeof一个对象得到的是所有数据成员的大小。

因为函数不存储在对象中,而是由编译器创建独立于所有对象的函数副本,所有对象共享函数副本。


3、访问对象数据成员和成员函数


对象名或对象引用的情况

a.b

a.b()

对象指针的情况

aPtr -> b

aPtr -> b()


4、工具函数


工具函数即private函数


5、析构函数


~类名()

在对象被撤销时被调用,某种意义上是与构造函数互补。


class Time{
     Time(...){...}
     ~Time(){...}
}
复制代码


注意:

不接收任何参数,不返回任何参数,void也不行。

一个类只能有一个析构函数,不允许重载。


6、对象传参


当对象作为参数或返回值时是传值参数,即传的是拷贝。

所以当要使用真正对象需要传引用或指针。


7、const对象\函数


声明对象 (注意位置):

void name() const {....}

对象声明const不能被修改,不能调用非const的成员函数。

成员函数声明const不能修改对象,同样不能调用非const的成员函数。


(1)可以对const成员函数进行非const重载。编译器根据对象性质选择相应函数,

const对象调用const函数;非const对象调用非const函数


(2)构造、析构函数不能声明const。


8、成员初始化器


int count;
const in num;
Time(int i, int j):count(i),num(j){...}
复制代码


所有数据成员都可以用成员初始化器来初始化,如上面的形式。

但是const数据成员和引用的数据成员必须使用成员初始化器进行初始化,不能通过赋值初始化。


(1) 成员初始化器在构造函数体执行前执行。


(2)建议将所有不修改对象的函数声明为const。


9、组成


即数据成员是一个其他类的对象。

如果构造函数没有初始化某个成员,那么会隐式的调用该成员的默认构造函数。如果该成员的类没有默认构造函数,编译报错。


10、friend函数和类(友元)


class A{
     friend class B;
     friend void b(...);
}
复制代码


友元可以访问原类中的非public成员和函数。

(1)友元关系不传递,不对称。

(2)友元函数不是成员函数

(3)友元最好在数据成员及函数之前声明。

(4) 友元模板类或模板函数的情况,需要提前定义,否则报错,如:


template<typename T> class B;
class A{
     friend class<T> B;
}
复制代码


(5) 友元是非模板类的成员函数,也需要提前定义。


10、this指针


因为是指针,所以:this -> x  或  (*this) .x


11、动态内存管理(new\delete)


Time time; 或 int num[24]; 这样在定义时需要将所有内存分配(所有成员内存或所有元素内存),即使未使用到,且不能改变。

使用动态内存管理实际上是在 自由存储区分配内存区域,通过delete释放。


Time *timePtr = new Time(....);
delete timePtr;
int *numsPtr = new int[24];
delete [] numsPtr;
复制代码


(1)释放时先调用析构函数,再回收内存。 数组释放时不加“[]”只调用第一个元素的析构函数。


(2)不释放会造成内存泄漏


(3)在编译时创建数组,大小必须用常量;而动态分配是可以使用任何表达式,如new int[a + b];


(4)动态分配一个对象数组时,会使用对象的默认构造函数初始化


(5)delete之后最好将指针设为0,如numsPtr=0。因为回收后内存空间中的信息还在,只是没有关系了,如果不注意访问了,会导致极端诡异无法复现的问题


(6)尤其注意循环中要使用new,否则会出错,如下:

for (int i = 0; i < 5; i++) {
     Node<int> node(i);
     Node<int> *ptr = &node;
}
复制代码


运行时会发现每次循环ptr指针指向的地址是不变的,也就是说所有的循环一致用一个Node对象而不是每次新建,这样会导致逻辑错误。改成new动态分配后,每次循环都是新的对象。


12、static


static数据成员只能被初始化一次。

int或枚举类型的const static数据成员可以在类定义中初始化;所有其他类型的数据成员必须在文件作用域(类定义外)定义并初始化。


xxx.h
class{
     ...
private:
     static int a;
     ...
}
xxx.cpp
...
int a = 1;
...
复制代码


(1) 在.cpp文件中定义初始化static数据成员时不能声明static,应该在.h中声明为static。


(2)如果成员是对象且有默认构造函数,可以不初始化。


(3)public static数据成员在类外部使用: 没有任何对象时Time::cout;有对象时time.count。


(4) 在static函数中不能使用this,否则编译错误。static函数不能被声明称const。


13、代理类


使用头文件虽然可以隐藏实现细节,但是依然暴露private数据成员或函数。

使用代理类,只有一个private成员,即被代理类的对象指针。


目录
相关文章
|
14天前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
19 4
|
14天前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
16 4
|
14天前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
14 1
|
24天前
|
存储 编译器 C++
【C++类和对象(下)】——我与C++的不解之缘(五)
【C++类和对象(下)】——我与C++的不解之缘(五)
|
24天前
|
编译器 C++
【C++类和对象(中)】—— 我与C++的不解之缘(四)
【C++类和对象(中)】—— 我与C++的不解之缘(四)
|
26天前
|
C++
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
51 1
|
15天前
|
存储 编译器 C语言
【C++打怪之路Lv3】-- 类和对象(上)
【C++打怪之路Lv3】-- 类和对象(上)
14 0
|
20天前
|
存储 编译器 C语言
深入计算机语言之C++:类与对象(上)
深入计算机语言之C++:类与对象(上)
|
24天前
|
存储 编译器 C语言
【C++类和对象(上)】—— 我与C++的不解之缘(三)
【C++类和对象(上)】—— 我与C++的不解之缘(三)
|
26天前
|
C语言 C++
C++番外篇——string类的实现
C++番外篇——string类的实现
19 0