#include <iostream>
#include <string>
#include <vector>
using namespace std;
/*
* 本例错误的原因是:set系列函数返回的是对象
* 所以返回时产生了一个临时的对象
*/
class Student
{
public:
Student()
:id_(0), name_(""), age_(0)
{
cout << "构造Student" << endl;
}
~Student()
{
cout << "销毁Student" << endl;
}
Student setId(int id)
{
id_ = id;
return *this;
}
Student setName(const string name)
{
name_ = name;
return *this;
}
Student setAge(int age)
{
age_ = age;
return *this;
}
void print(ostream &os) const //针对不同的流的输出函数写法
{
os << id_ << " " << name_ << " " << age_ << endl;
}
private:
int id_;
string name_;
int age_;
};
int main(int argc, const char *argv[])
{
Student s;
s.setId(11).setName("zhangsan").setAge(88).print(cout);
s.print(cout);
return 0;
}
当main里面做如下处理的时候
student s;
s.setId(11).setName("zhangsan").setAge(88).print(cout);
再调用s.print(cout)的时候,首先打印出来
11 zhangsan 88
11
- 当我们在析构函数里面添加一个cout << "销毁空间" << endl;的时候,很明显可以看出来该句运行后总共输出了三次,从而推断出上面那行代码总共生成了三个类对象,由于return的不是引用,所以返回的不是原始对象,而是set的对象的值copy版本
- 调用第一次set的时候,成功set了s里面的一个元素name_,然后返回s的值copy版本(另一个student类型)....最后打印最后的一个临时student类型,但是s里面,只初始化了一个元素
- 改进:在每一个set前面加上引用&
- 扩展:要保证 s.setId(11).print(cout).setName("zhangsan").setAge(88).print(cout);能够正常输入,需要怎么修改源程序-->print前加上引用&,去掉后面的const,同时将void改为student,添加一行return *this,**同时必须补充一个const Student &print(ostream &os) const **的函数重载
类函数里面的static
定义
private 里面可以定义static变量,public里面可以定义static函数
调用
static 函数没有隐式参数、不能为const、不能调用普通成员,普通函数可以调用static成员。
对于Date 类里面的static print()函数,可以使用
- Date::print()
- date.print() date为Date类
两种方式来调用
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Test
{
public:
Test()
{
count++;
}
~Test()
{
count--;
}
static void print()
{
cout << "当前对象个数: " << count << endl;
}
private:
static int count; //表示对象的个数
};
int Test::count = 0;//类里面的static变量,在使用前也需要初始化!
int main(int argc, const char *argv[])
{
Test::print();
Test t1;
t1.print();
Test t2;
t1.print();
t2.print();
return 0;
}
类函数的声明和定义
- 函数可以定义在类里面,也可以定义在类的外面(一般定义在外面,原因见第二条)
- 函数定义在class内部,默认为内联函数(编译时直接展开,不是调用)
- 定义的方式如下
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Student
{
public:
Student();
Student(int id, const string name, int age);
void print() const;
private:
int id_;
string name_;
int age_;
};
Student::Student()
:id_(0),
name_(""),
age_(0)
{
}
Student::Student(int id,
const string &name,
int age)//构造函数在类外面定义的写法
:id_(id),
name_(name),
age_(age)
{
}
void Student::print() const//非构造函数在类外面定义的方法
{
cout << "hello" << endl;
}
允许另外的类或者函数调用本类的private值
C++中的friend声明是一种单向关系。例如A声明friend class B表示B是A的friend,可以访问A的private数据,但是反过来不成立。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Test
{
public:
friend class Other; //声明Other是Test的朋友
friend void bar(const Test &t);//friend -->使访问private元素成为可能
private:
int x_;
int y_;
};
class Other
{
public:
void foo(Test &t)
{
t.x_ = 10;
t.y_ = 20;
}
};
void bar(const Test &t)
{
cout << t.x_ << endl;
}
int main(int argc, const char *argv[])
{
Test t;
return 0;
}