eg.
#include<iostream>
using namespace std;//使用命名空间,如若不是用则cout之类的函数名无法识别,必须在函数前加作用域即:std::cout
int main()//返回值必须为int型
{
cout<<"Hello World!"<<endl;
return 0;
}
命名空间:
namespace test
{
void show();
int print();
} //后面没有分号
函数重载:函数名相同参数不同,不能通过返回值来判断,这样的函数称为重载函数
函数的默认参数必须从用往左赋值。
若最左边的参数有值,其后面的参数必须有值,否则报错
引用:
int &b=a;//把b作为a的别名//标准C++中不能引用数组
new:
int *p = new char ; //delete p;
类:
注意事项:1.类名首字母大写//防止不必要的错误
2.结束的地方一定要有分号。
3.类名称之后紧跟的是私有成员
4.程序运行时类不存在,存在的只有对象
5.类内函数可以直接访问私有数据成员,类外函数不可
内联函数:
1.类内实现
2.使用inline关键字
构造函数:
1.将对象初始化到某一状态
2.在对象创建时自身调用
3.函数名是类名,没有返回值。
4.允许函数重载
5.当匹配所有情况时,在声明构造函数时需初始化但函数的实现部分参数不可带形参值
eg.
Point(int a = 0,int b = 0,int c = 0);//在类内函数的声明
Point::Point(int a,int b,int c)//在类外函数的实现
{
。。。。。。
}
拷贝构造函数
1.函数名是类名//一种特殊的构造函数,只是用对象初始化另一个对象
2.没有返回值
3.造型 Point(const Point &other);
返回对象与返回引用
返回对象时需创建临时对象,函数中的返回值全以拷贝的形式拷贝到被调用函数栈中的一个临时对象,表达式结束,临时对象即析构
返回引用时可以减少一个复制对象的过程,从而减少内存开销
返回对象时系统自动调用拷贝构造函数。
析构函数
1.~Point();
2.无参无返回值
3.做侍候清理工作
this指针:只会出现在成员函数中
静态数据成员:
class Student{
private:
static int number;
string name;
};
int Student::number = 0;
将数据成员设计成静态数据成员后,该成员的变化仍然会在每次创建对象之后的名称赋值中反映出来。反映的结果存放在专属于Student类名空间的全局数据区中,不属于各个对象。整个类中只有一份number拷贝,所有的对象都共享这份拷贝。因此,输出学生总数时,访问的是惟一的静态数据成员,它不会因对象而异了。
由于静态成员脱离对象而存在的性质,所以该实体应在所有对象产生之前存在,因此,更适当的时机是在程序启动的时候,做其初始化。上面的初始化语句,似乎像个全局变量,但它属于Student类名空间。
该实体在程序中的唯一性,要求其不能跟着Student类定义放在头文件中,但它又确实Student类得一员,所以,放在类得实现代码中是最合适的。
定义静态成员的格式不能重复static关键字,但必须在成员名前冠以类名加域操作符,以表示成员的类属。如果不讲其初始化,则系统将为该成员清0。
静态成员函数
上面的静态成员数据例子中,访问静态数据成员是放在成员函数set中的。也就是说,必须创建了对象,由对象捆绑一个成员函数,去操作静态成员。难道对象不存在时,就不能观察静态数据成员了?如果一个有一个过程专门处理某类的对象个数,难道还要专门创建一个多余的对象来达到访问静态成员的目的?显然这并不是理想的方法。然而,让外部直接访问静态成员有失安全性和可维护性。如果一个数据置于大庭观众之下,损坏了谁也不认账,找谁说理去?因此与数据成员一样,将静态成员做成私有的,用静态成员函数去访问静态数据成员是合适的。
#include <iostream>
using namespace std;
class Student
{
public:
void set(string str){
name = str;
++ number;
}
static int printNumber(){cout << number << "total numbers\n"}
void print(){cout << name << "-> students are" << number << "numbers\n";}
};
int Student::number = 0;
void fn()
{
Student s1;
s.set("Jenny");
Student s2;
s2.set("Randy");
s1.printNumber();
}
int main()
{
Student s;
s.set("Smitch");
fn();
Student::printNumber();
}
在类中声明静态成员函数,要在成员函数名前加上关键字static。静态成员函数并不受对象的牵制,可以用对象名调用静态成员函数,也可以用类名加上域操作符调用静态成员函数,这时候,将它看做是某个名空间的一个函数。
静态成员函数的实现位置与成员函数的实现位置应该是一起的,静态成员函数如果不在类中实现,而在类得外部实现时,类名前应免去static关键字。成员函数的静态性只在第一次声明的时候才是必要的。
因为静态成员函数可以不以捆绑对象的形式调用,静态成员函数被调用时,没有当前对象的信息,所以静态成员函数不能访问数据成员。
static int printNumber(){cout << name << number << "total numbers\n";}
则编译通不过。这并不是说它没有私有数据访问的权限,如果在静态成员函数,给它传递一个Student对象:
static int printNumber(Student &s)
{
cout << "My name is " << s.name << "\n";
cout << s.number << "total numbers\n"
}
那么,访问私有数据便是它的权利。
友元函数:
1.声明时需用关键字friend修饰,实现时不需要
2.友元函数不属于类,他是一个类外函数。
3.友元关系不能传递
4.可以定义友元类,关系是单向的。
5.友元类需前向引用声明,只能使用被声明的符号,不能类的任何细节。
我们已知道类具有封装和信息隐藏的特性。只有类得成员函数才能访问类得私有成员,程序中的其他函数时无法访问私有成员的。非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性。另外,应该看到某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运行效率。
为了解决上述问题,提出一种是用友元得方案。友元是一种定义在类外部的普通函数或类,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但它可以访问类中的私有成员。友元得作用在于提高程序的运行效率,但是,它破坏了类得封装性和隐藏性,使得非成员函数可以访问类得私有成员。
常对象和常对象成员
一、常对象
1.格式:const 类名 对象名(参数列表);
如声明box类的一个对象为常对象:const box b1(3,4,5);或者:box const b1(3,4,5);
2.注意:
* 常对象的数据成员必须是常变量,而且必须要有初值。
* 常对象只能调用其常(const 型)成员函数,不能调用非const型成员函数。而常成员函数可以访问常对象数据成员,但不能修改
* 常对象只是其数据成员是const型的,它的成员函数可以是const型或非const型。
* 常对象的数据成员只能引用,不可修改,如果一定要修改,可将需要修改的数据成员声明为mutable;
如:mutable int count;
#include <iostream>
using namespace std;
class box
{
public:
box(int =0,int =0,int =0);
int print() const;//常成员函数声明
private:
int wid,hig;
mutable int len;//声明常对象中的len值可以修改
};
//construct function
box::box(int l,int w,int h):len(l),wid(w),hig(h)
{
}
//const member function
int box::print()const
{
len = len * 2;
cout << len << "*" << wid << "*" << hig << "=" << len * wid * hig << endl;
}
//main function
int main()
{
const box b1(2,3,4);//常对象,则只能调用常成员函数
b1.print();
return 0;
}
二、常对象成员(常数据成员和成员函数)
1、常数据成员
在类体中将数据成员声明为const型,即为常数据成员,值得注意的是,因为不能常数据成员赋值,所以对常数据成员的初始化必须要用构造函数的初始化列表来完成。
如在time类体中声明了为常数据成员hour,则:
time::time(int h)
{
hour = h;//非法
}
time::time(int h);hour(h)
{
}
2.常成员函数
常成员函数含义是函数体得代码不能修改实参的值,但是可以修改形参的值
a.常成员函数不能更新对象的数据成员
b.不能调用该类中没有const修饰的成员函数
格式:返回类型 函数名称 (参数列表) const//函数声明
返回类型 所属类名::函数名称(参数列表) const //函数定义
注意:关键字const是函数的一部分,在函数声明和定义部分都必须包含。
常成员函数可以引用const或非const型数据成员,但只能引用,不可修改。
常成员函数不能调用另一个非const型成员函数
派生类构造函数
派生类::派生类名(基类所需形参,本类成员所需形参):基类名(参数表)
{本类成员初始化。。。}
组合类和继承类一起出现,构造函数的调用顺序
1.组合和继承同时出现,继承优先
2.继承通过类名去触发构造函数,构造顺序和继承顺序一样
3.组合通过对象名触发其构造函数,构造顺序和生命顺序一样。
运算符重载
声明形式
函数类型 operator 运算符(形参){。。。。。}
1.重载为类的成员函数//参数个数=原操作数个数-1(后置++、--除外)
2.重载为友元函数时 参数个数=原操作数个数
3.前置单目运算符,重载函数没有形参,对于后置单目运算符,重载函数时需要有一个整形形参
如:Clock &operator ++();//前置单目运算符
Clock operator ++(int);//后置单目运算符
虚函数:
1.虚函数是动态绑定的基础
2.是非静态成员函数
3.在类的声明中,在函数原型之前写virtual
4.本质:不是重载声明,而是覆盖
5.调用方式:通过基类指针或引用,执行时会根据指针指向的对象的类,决定调用哪个函数。
抽象类:
带有纯虚函数的类
纯虚函数:virtual 类型 函数名(参数表)=0;
函数模板:
建立一个通用函数,其函数类型和形参类型不具体制定,用一个虚拟的类型表示。
template<typename T>//或者template<class T>
T name(T a,T b)
{
。。。。
return T;
}