// win32Test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
class A
{
public:
A(){;}
~A(){;}
public:
int fun(A& one)
{
//表达式1:错误
//return one.fun(this);
//表达式2:错误,cannot convert parameter 1 from 'class A *const ' to 'class A &'
//m_iX = fun(this);
//return m_iX;
//表达式3:正确
int* const pX = &one.m_iX;
}
private:
int m_iX;
//const B& b1;//正确,可以这样声明,类的成员变量可以是常引用,但是在构造函数必须初始化
//B& b2;//正确,可以这样声明,类的成员变量可以是常引用,但是在构造函数必须初始化
};
class B
{
public:
B();
~B();
public:
int Get(B& b)
{
return b.m_iY;//正确,类的内部可以直接访问私有变量
}
int Get()
{
return m_pOne->m_iY;//正确,类的内部可以直接访问私有变量
}
public:
friend int global_getB(B& b);//定义成友元函数
private:
int m_iY;
B* m_pOne;
};
int global_getB(B& b)//全局函数
{
return b.m_iY;//正确,友元函数可以直接访问私有变量
}
class C
{
private:
C(){}
~C(){}
public:
friend class D;
};
class D
{
public:
D(){}
~D(){}
public:
C* GenFun()
{
return new C();//可以通过友元类的方式创建对象C
}
};
//C++访问类的私有成员变量的方法:
//方法1:set/get接口
class E
{
int i;
public:
E()
{
i = 50;
}
int get() const {return i;}
void set(int k) {i = k;}
};
//方法2:友元类
class F
{
int i;
public:
F()
{
i = 50;
}
friend class G;
};
class G
{
public:
F f;
int get()
{
return f.i;
}
};
//方法3:友元函数
class H
{
int i;
public:
friend int global_getH(H& h);
};
int global_getH(H& h)
{
return h.i;
}
int main(int argc, char* argv[])
{
//B& b3;//错误,不可以这样定义,必须初始化
//C c;//错误,类c的构造函数是私有的,必须通过静态函数或者友元的方法来实例化对象
return 0;
}
两道问答题:
//在声明类中的构造函数、析构函数、纯虚函数、静态成员函数、非静态的成员函数以及全局函数作为类的友元函数时,哪些可以是常量成员函数?
//只有纯虚函数、非静态的成员函数可以是常量成员函数。
//(这题有点问题,析构函数可以是纯虚函数,但不能是常量函数)
//1、声明带有 const 关键字的成员函数指定,函数是 “只读”函数,在它被调用的时候不会修改对象。一个常数成员函数不能修改任何非静态数据成员或调用不是常数的任何成员函数。
//若要声明常数成员函数,请在参数列表的右括号后放置const关键字。声明和定义中均要求该const关键字。
//2、构造函数和析构函数为了生成和释放成员变量,显然不能是const。
//3、静态成员函数不能是常量成员函数的原因:
//(1)const成员函数是包含this指针的。这明显不被static函数允许。
//(2)因为static成员不是任何对象的组成部分,所以static成员不能被声明为const,毕竟将成员声明为const就是承诺不会修改该函数所属对象。
//(3)const针对对象才有意义。const是基于对象的;static 是基于类的。
//4、全局函数作为类的友元函数时,它是定义在类外的普通函数,并不属于类的成员函数。
//通常类A的拷贝构造函数的原型写为A(const A&);,请问为什么参数一定要使用引用形式?使用const修饰符除了可以防止修改传递给构造函数的实参外,还有什么作用?
//A(const A& one ).当调用此拷贝构造函数时,需将参数压栈,若不使用&,就需要在栈内创建一个one的副本,而这需要用拷贝构造函数。这样就会形成递归调用。
//使用const,还允许用一个常量对象作为样本,来构造一个新的对象。