实现一个自定义String类时,希望输出其内容,于是添加了<<输出函数,总是出错。
原来是没有进行友元声明。还遇到一个问题,就是在成员函数中类对象直接访问了private对象,当时直接不解,经过网上查阅资料才了解。
原来类对象作为类成员函数的参数时,是可以访问private成员的。
类对象访问私有成员情形还有:protected继承。
*运算符重载规则:*
当运算符重载为类的成员函数时,函数的参数个数比原有操作数个数要少
一个(后置“++”,“--”除外),也就是说,一元操作符的参数个数为0,
二元操作符的参数个数为1;
而运算符重载为类的友元函数时,函数的参数个数与原有操作数个数相同
(后置“++”,“--”除外),
也就是说,一元操作符的参数个数为1,二元操作数的参数个数为2。
这是因为,当重载为类的成员函数时,如果某个对象使用重载了成员函数,
自身的数据可以直接访问,就不用再放在函数表中进行传递,
这样该类本身也作为一个操作符参与了计算。
总结:
输出重载<<操作符;可以使用成员函数,也可是使用友元函数,
但函数友元函数使用上方便一些。
因此输入输出运算符一般重载为友元函数。
C++访问控制:
关键字private,它描述了对类成员的访问控制。
使用类的对象方法可以直接访问私有成员函数和变量。
类的对象即实例只能通过公共成员函数来访问私有变量和私有成员函数。
因此公有成员函数成为对象的私有变量访问的桥梁。
在C++中,在类的成员函数的参数为此类类型时,
可以通过类类型的对象直接访问私有成员变量。
或者在成员函数中使用临时对象来直接访问私有变量。
class String {
public:
String(const char * str = NULL);
String(const String &other);
~String();
String & operator =(const String &other);
String & operator +(const String &other);
inline ostream&
operator <<(ostream& os) //成员方式
{
os << "inline method, " << p_data;
return os;
};
friend ostream&
operator <<(ostream& os, const String &other);//友元方式
bool operator ==(const String &other);
int getLength();
private:
char *p_data;
};
String::String(const String& other)
{
if (!other.p_data)
{
p_data = NULL;
}
int len = strlen(other.p_data) + 1;
p_data = new char[len];
strcpy(p_data, other.p_data);
}
String::String(const char* str)
{
if (str==NULL)
{
p_data = new char[1];
*p_data = '\0';
}
else
{
int length = strlen(str);
p_data = new char[length + 1];
strcpy(p_data, str);
}
}
String::~String()
{
if (p_data)
{
delete[] p_data;
p_data = NULL;
}
}
int String::getLength()
{
return strlen(p_data);
}
String & String::operator =(const String &other)
{
if (this != &other)
{
delete[] p_data;
if (!other.p_data)
{
p_data = NULL;
}
else
{
p_data = new char[strlen(other.p_data) + 1];
strcpy(p_data, other.p_data);
}
}
return *this;
}
ostream&
operator <<(ostream& os, const String &other)
{
os << "friend method, " << other.p_data;
return os;
}
String & String::operator +(const String &other)
{
return *this;
}
bool String::operator ==(const String &other)
{
if (getLength()!= strlen(other.p_data))
{
return false;
}
else
{
return strcmp(p_data, other.p_data)?false:true;
}
}
测试:
int main()
{
String aa(“hello world!”);
String bb(“nihao!”);
cout << aa <<" "<< bb << endl;
aa << cout << endl;
bb << cout << endl;
cout << aa.getLength() << endl;
}
输出结果: