类的访问控制
private:只有通过本类对象才能够使用下属的方法才能够改变成员变量等。
public:公开本类对象的属性,外部可以随便改变。
protected:对本类和派生类公开,仅。
作用域控制符::
定义成员函数时,
void Person::setAge(unsigned n)
{}
常指针this
指针this可用于类的成员函数里,用于指代函数调用相关联的对象。
this是一个系统变量,和其他常规变量有所区别,不能对它进行求地址和对其赋值。
this仅仅用于非静态函数中。
静态函数/静态变量参见别人的总结:
这里。。
Constructor,构造函数
构造函数定义的几种方式:
Date today = Date(12,12,2001);
Date this_day(12,12,2001);
构造函数由系统自动调用,人为无法干涉,但能够分析。当且仅当对象创立的时候,调用。
承担实例对象生成和初始化的任务。
构造函数能够被重载,每一个重载的构造函数都应该有一个独特的签名。仅仅返回值类型不同的函数,不能共存。(签名不包括返回值)
构造函数能够缺省参数。如:
Date(int dd=0,int num=0.int yy=0);
另外,当一个类中没有定义构造函数时,则系统会给出一个缺省的空函数体的构造函数。只要程序员定义了任何一个明确的构造函数,那么系统不会再给出任何构造函数了。
如以下情况:
class Emp{
public:
Emp(unsignedn ID){id=ID;}//inline function
//...
private:
unsigned id;
Emp();//缺省的构造函数在private区。
}
int main()
{
Emp elvis;//Error:no public default constructor
return 0;
}
如果将private区的Emp()注释掉,则完全没有缺省的constructor;
class Emp {
public:
Emp( unsigned ID ) { id = ID; }
//…
private:
unsigned id;
// Emp( );
};
int main( ) {
Emp elvis;//Error:no matching function for call to 'Emp::Emp()'
Emp cher( 111222333 );
return 0;
}
拷贝构造函数:
拷贝构造函数的参数为引用类型。
Person(const Person&);
如果编程者没给出一个拷贝构造函数,那么编译器给出。如果给出模板类的一个动态分配内存的指针,则编译器给制造一个并复制之。
拷贝构造函数的定义中,参数类型应该做出改变。
Namelist(const Namelist &d);
If the user does not provide a copy constructor, the compiler does.
The class author typically defines a copy constructor for a class whose data members include a pointer to dynamically allocated storage.
Namelist d2(d1);
析构函数,Destructor
当对象即将销毁时,系统会自动调用析构函数。
析构函数没有参数,所以不能重载。
析构函数用来释放内存空间。
当对象的生命期结束时,或程序显示地用delete删除时,系统会自动调用对象所属类的析构函数。
对象创建的次序为:先创建父类,其次是对象成员,最后是本身。
先创建的类先执行构造函数,先创建的类最后执行析构函数。
因为后者的析构可能涉及前者,所以得保留一下前者。
数据变量函数的其他性质
如果某个表示符在外层中声明,且在内层中没有同一标识符的声明,则在内层可见这一个标识符。
对于两个嵌套的作用域,如果在内层作用域内声明了与外层作用域同名的标识符,则外层的同名标识符不可见于内层。
对象的静态生存期与程序运行期相同,在程序装载时就准备好了空间。定义时要冠以关键字static。
动态变量,其实默认省略了关键字dynamic。
const的用法
对于既需要共享,又需要防止改变的数据应该声明为常类型,关键词为const。对于不改变对象状态的函数应该声明为常函数。
常对象:必须进行初始化,不能为更新。
常引用:被引用的对象不能被更新。
const int & a=b;
//a作为变量b的别名,不能根据引用a对变量b进行更改
c++中定义常量:
在定义const指针时,若const出现在星号左边,表示被指针指着的事物是不可更改的常量。
若const出现在星号右边,表示指针自身是常量。
char greeting[]="hello";
char *p=greeting;//这是存储在程序的文字常量区的,不可更改。
const char *p=greeting;
char *const p=greeting;
const char *const p = greeting;
常成员函数:
int g(int k) const;
const关键字也是函数类型的一部分。
常成员函数不修改任何数据成员,通常用作只读函数。
另外,const关键字可以被用于参与对重载函数的区分。
通常常对象只能调用常成员函数。
插一句,引用可以作为左值。
C & g()
{
return c1;
}
int main()
{
g()=9;
}
void set(const string &n){num=n;.....}
这样,对参数n不能进行修改。
常方法:
class A{
public:
int get()const{return num};
......
在类的常方法中只能访问数据成员的值,不能修改数据成员的值 也不能调用其他修改数据成员值的方法!!
}
const int g();
这种函数是防止修改g函数的返回值。
通常常对象只能调用它的常成员方法:
class R{
public:
R(int r1,int r2):r1(r1),r2(r2){}
void print();
void print()const;
private:
int r1,r2;
}
void R::print()
{
cout<<r1<<":"<<r2<<endl;
}
void R::print()const
{
cout<<r1<<";"<<r2<<endl;
}
int main()
{
R a(5,4);
a.print();
const R b(5,3);
b.print();
}
运行结果:
5:4
5;3
类中的静态数据成员和方法
在类中定义static型变量,类只为其分配一块空间,所有类的对象都共享。
static变量是 class data member,而其他的变量是object data member;
类中的静态变量,必须在类外进行定义和初始化。
class Task{
public:
//......
private:
static unsigned n;
};
unsigned Task::n=0;
类外代码可以通过类型::变量名来调用静态成员函数。
静态成员函数只能引用属于该类的静态数据成员或静态成员函数。
另外,
在一个作用域内定义的静态变量,设置后不会随着作用域的流过而释放,再次调用该作用域,则不会重新定义。
class C {
public:
void m( ) {
static int s = 0;
cout << “s=”<<++s << '\n';
}
private:
int x;
};
int main( ) {
C c1, c2, c3;
c1.m( ); c2.m( ); c3.m( );
return 0;
}
函数的指针
函数占据连续的一个内存单元,有指向函数的指针,能够指向函数的内存首地址。
#include <stdio.h>
#define GET_MAX 0
#define GET_MIN 1
int get_max(int i,int j)
{
return i>j?i:j;
}
int get_min(int i,int j)
{
return i>j?j:i;
}
int compare(int i,int j,int flag)
{
int ret;
//这里定义了一个函数指针,就可以根据传入的flag,灵活地决定其是指向求大数或求小数的函数
//便于方便灵活地调用各类函数
int (*p)(int,int);
if(flag == GET_MAX)
p = get_max;
else
p = get_min;
ret = p(i,j);
return ret;
}
int main()
{
int i = 5,j = 10,ret;
ret = compare(i,j,GET_MAX);
printf("The MAX is %d\n",ret);
ret = compare(i,j,GET_MIN);
printf("The MIN is %d\n",ret);
return 0 ;
}