#include#include #include #include #include #include #include #include #include
#include #include #include #include using namespace std; //先编译成员声明,直到类全部可见之后才编译成员函数的定义 class Person{ //struct的默认访问权限是public,class的默认访问权限是private //友元函可以让非成员函数访问类的私有成员 //友元函数可以声明还未声明的函数,但是直到该函数被声明后才可以调用它(即使是声明友元类的成员调用该函数也的在该函数声明才可调用) friend std::istream &read(std::istream &is, Person &obj); //非成员函数以及静态成员函数后面不能加const修饰符 friend std::ostream &print(std::ostream &os, const Person &obj); friend std::istream &operator >>(std::istream &is, Person &obj);//operator返回的是值(临时变量),而&operator返回的是引用,可以作为左值 friend std::ostream &operator <<(std::ostream &os, Person &obj); //cout << a << b;如果需要连续使用运算符那就需要返回&类型。 &operator //(cout << a) << b;(cout << a)的返回值是临时变量,不能作为左值。这里需要表示为cout << a; cout <::size_type; //类型名通常定义在类的开始处,便于后面成员声明时使用 public: void addPerson(const Person &obj);//非常量左值引用不能做为右值,所以加上const void printPerson(size i); private: std::vector persons; }; class Y; //前向声明,可以定义指向这种类型的指针或者引用,也可以声明该类型为参数或者返回值的函数(但是不能定义) class X{ Y *y = nullptr; }; class Y{ //友元函数可以声明还未声明的函数,但是直到该函数被声明后才可以调用它(即使是声明友元类的成员调用该函数也的在该函数声明才可调用) //friend void f(); X x; //Y getxx(); }; //构造函数初始化列表初始化顺序与成员声明顺序一致,如果用后声明的成员初始化先声明的成员会出现未定义的错误
#include "test.h" Person::Person(std::istream &is) { read(cin, *this); //解引用,把this指向的person对象传递给read函数 --*this即表示this指向的Person对象 } Person::Person(const Person &obj) { this->Name = obj.Name; this->Address = obj.Address; } inline Person &Person::setAddress(string &address) { this->Address = address; return *this; } inline string Person::getName() const { std::cout << "use const getname" << std::endl; std::cout << this->Name << std::endl; return this->Name; } inline string Person::getName() { std::cout << "use normal getname" << std::endl; std::cout << this->Name << std::endl; return this->Name; } inline string Person::getAddress() const { std::cout << this->Address << std::endl; return this->Address; } void Person::getCount() const { ++count; //虽然是一个const函数,但是任然能改变count的值,因为count定义成了mutable(可变的) std::cout << count << std::endl; } std::istream &read(std::istream &is, Person &obj) { is >> obj.Name >> obj.Address; return is; } std::ostream &print(std::ostream &os, const Person &obj) { os << obj.Name << " : " << obj.Address << "n"; return os; } std::istream &operator >>(std::istream &is, Person &obj) { is >> obj.Name >> obj.Address; return is; } std::ostream &operator <<(std::ostream &os, Person &obj) { os << obj.Name << " : " << obj.Address << "n"; return os; } void Man::addPerson(const Person &obj) { this->persons.push_back(obj); } void Man::printPerson(size i) { this->persons[i].getAddress(); } int main() { string name("jzj"); string address("cd"); Person my(name, address); //构造 my.getCount(); //string myaddr = "wy"; //my.setAddress(myaddr).getAddress(); Man man; man.addPerson(my); man.printPerson(0); // man.printPerson(1); system("pause"); return 0; }
不能用非常量左值作为右值
声名普通友元friend xxxx
声名友元函数,该函数为另一个类的成员函数friend void(返回值) T::xx (另一个类的成员函数)
声名友元类friend class T
当定了其他构造函数时,需要自己定义默认构造函数(也可以T() = default让系统定义一个默认构造函数)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)