后天考c++,但这几天得甲流了,特别难受!复习c++的时候复习着忘着,所以用csdn记录一下不熟悉的知识点,等后天考前再看一遍!
#include
// 定义一个模板类
template
class Pair {
private:
T1 first;
T2 second;
public:
// 构造函数
Pair(T1 f, T2 s) : first(f), second(s) {}
// 获取第一个元素
T1 getFirst() const {
return first;
}
// 获取第二个元素
T2 getSecond() const {
return second;
}
};
int main() {
// 使用模板类 Pair,其中 T1 为 int,T2 为 double
Pair myPair(1, 3.14);
// 输出结果
std::cout << "First: " << myPair.getFirst() << std::endl;
std::cout << "Second: " << myPair.getSecond() << std::endl;
return 0;
}
T:类型参数,实际上是一个虚拟的类型名;
class 和typename的作用相同,都表示“类型名”,可互换
格式: <类型> &<引用变量名> = <原变量名>;
其中原变量名是定义好的变量
不能建立引用的引用,也没有引用的指针
引用的用途主要是用来作函数的参数或函数的返回值
用struct声明的类,如果对其成员不作private或public的声明,系统将其默认为public
而用class定义的类,如果不作private或public声明,系统将其成员默认为private,在需要时也可以自己用显式声明改变
如果希望成员是公用的,使用struct比较方便,如果希望部分成员是私有的,宜用class
建议尽量使用class来建立类,写出完全体现C++风格的程序
每个对象所占用的存储空间只是该对象的数据部分所占用的存储空间,而不包括函数代码所占用的存储空间
不同的对象使用的是同一个函数代码段,它怎么能够分别对不同对象中的数据进行操作呢?
C++为此专门设立了一个名为this的指针,用来指向不同的对象
应当说明: 常说的“某某对象的成员函数”,是从逻辑的角度而言的,而成员函数的存储方式,是从物理的角度而言的,二者是不矛盾的
如果用户未定义构造函数,系统会自动提供一个默认构造函数,但函数体是空的,不提供初始化作用
如果用户仅仅写了一个有参构造函数,那么上述这个默认构造函数就会“消失”,比如:
构造函数也可以由默认值,应该在声明构造函数时指定
声明构造函数时,形参名可以省略,Box(int = 10,int = 10,int = 10)
构造函数带默认值时很容易和重载的构造函数产生歧义性,比如
Box();
Box(int = 10,int = 10,int = 10);
析构函数不能被重载;一个类可以有多个构造函数,只能有一个析构函数
static局部对象,只在main函数结束或调用exit函数结束程序时调用析构函数
全局对象,则在程序的流程离开其作用域时(如main函数结束或调用exit函数) 时调用析构函数
对于静态局部对象,只在程序第一次调用此函数建立对象时调用构造函数一次,在调用结束时对象并不释放,因此也不调用析构函数,只在main函数结束或调用exit函数结束程序时,才调用析构函数
定义常对象的形式为:
类名 const 对象名[(实参表列)];
或
const 类名 对象名[(实参表列)];
常对象必须要有初值,所有成员的值都不能被修改。凡希望保证数据成员不被改变的对象,可声明为常对象
如果一个对象被声明为常对象,则不能调用该对象的非const型的成员函数(除了由系统自动调用的隐式的构造函数和析构函数)
引用常对象中的函数成员,只需将该成员函数声明为const即可。如
void get_time( ) const; //将函数声明为const
t1.get_time( ); // 可行
修改常对象中的某个数据成员的值,需要对该数据成员声明为mutable,如
mutable int count;//可以用声明为const的成员函数来修改它的值
常数据成员
和一般常变量相似,常数据成员的值是不能改变
只能通过构造函数的参数初始化表对常数据成员进行初始化。不能在构造函数中对常数据成员赋初值的方法。
Time∷Time(int h){hour=h} //非法
Time∷Time(int h):hour(h){} //通过参数初始化表对常数据成员初始化
常对象的数据成员都是常数据成员,因此常对象的构造函数只能用参数初始化表对常数据成员进行初始化
常成员函数
如果将成员函数声明为常成员函数,则只能引用本类中的数据成员,而不能修改它们,例如只用于输出数据等
常成员函数可以引用const数据成员,也可以引用非const的数据成员
const数据成员可以被const成员函数引用,也可以被非const的成员函数引用
如果已定义了一个常对象,只能调用其中的const成员函数,而不能调用非const成员函数
常对象只保证其数据成员是常数据成员,其值不被修改
常成员函数不能调用另一个非const成员函数
如果想在同类的多个对象之间实现数据共享,也不要用全局对象,可以用静态的数据成员
静态数据成员不属于某一个对象,在为对象所分配的空间中不包括静态数据成员所占的空间。静态数据成员是在所有对象之外单独开辟空间。只要在类中定义了静态数据成员,即使不定义对象,也为静态数据成员分配空间,它可以被引用
静态数据成员不随对象的建立而分配空间,也不随对象的撤销而释放(一般数据成员是在对象建立时分配空间,在对象撤销时释放)。静态数据成员是在程序编译时被分配空间的,到程序结束时才释放空间
静态数据成员可以初始化,但只能在类体外进行初始化。
一般形式为
数据类型类名∷静态数据成员名=初值;
int Box∷height=10;
注意: 不能用参数初始化表对静态数据成员初始化
如果未对静态数据成员赋初值,编译系统会自动赋予初值0
静态成员函数没有this指针,在C++程序中,静态成员函数主要用来访问静态数据成员,而不访问非静态成员
在一个静态成员函数中:
cout<
C++不允许用户自己定义新的运算符,只能对已有的运算符进行重载。
C++中绝大部分的运算符允许重载。不能重载的运算符只有5个:
. (成员访问运算符)
* (成员指针访问运算符)
∷ (域运算符)
sizeof (长度运算符)
?: (条件运算符)
重载不能改变运算符运算对象(即操作数)的个数。
重载不能改变运算符的优先级别。
重载不能改变运算符的结合性
重载运算符的函数不能有默认参数,否则就改变了运算符参数的个数。
重载的运算符必须和用户定义类型的对象一起使用,其参数至少应有一个是类对象(或类对象的引用)。参数不能全部是C++的标准类型,以防止用户修改用于标准类型数据的运算符的性质。
用于类对象的运算符一般必须重载,但运算符“=”和“&”不必用户重载
自增运算符重载示例:
#include
class Counter {
private:
int count;
public:
Counter() : count(0) {}
// 重载前置自增运算符 (++var)
Counter& operator++() {
count++;
return *this; // 返回递增后的对象引用
}
// 重载后置自增运算符 (var++)
Counter operator++(int) {
Counter temp(*this); // 创建一个副本用于保存递增前的值
count++;
return temp; // 返回递增前的对象副本
}
void display() const {
std::cout << "Count: " << count << std::endl;
}
};
int main() {
Counter myCounter;
// 使用前置自增运算符
++myCounter;
myCounter.display();
// 使用后置自增运算符
Counter anotherCounter = myCounter++;
myCounter.display();
anotherCounter.display();
return 0;
}
剩下的内容,在下面三篇文章中写的比较详细:
c++ 运算符重载
c++ 继承和派生
c++ 多态和虚函数