构造函数
当我们需要在对象创建时初始化一些数据的时候,我们不可能提供一个普通的成员方法供程序猿在对象创建后调用。因为如果程序猿故意或者无意间忘记了调用该方法,就可能导致程序出现偏离预期的结果。为了防止这种情况的发生,C++中提供了一种特殊的成员函数–构造函数。
声明和定义
构造函数与普通函数在声明与定义上别无二致,除了不需要声明返回值。
在声明中添加如下代码
Student(std::string name,int chScore,int enScore,int mathScore);
在实现中的一般实现方式为
Student::Student(std::string name,int chScore=0,int enScore=0,int mathScore=0){
cout<<"您好呀! "<<name<<",很高兴见到你!"<<endl;
setName(name);
setChScore(chScore);
setEnScore(enScore);
setMathScore(mathScore);
}
引用参数与构造函数
当我们在类声明时声明了一个引用参数,而引用参数又要求必须初始化,且只能初始化一次。应该怎么办呢?这是我们需要一种新的成员初始化方式
std::string & name;
比如我们的name属性是引用类型,那么我们需要在每一个构造方法实现的参数列表后面加上这样的初始化器
Student::Student(std::string &n):name(n){
......
}
Student::Student(std::string &n,int chScore,int enScore,int mathScore):name(n){
......
}
如果我们有多个引用需要初始化,这些构造器只需要使用,逗号分割,并且除了引用类型,任何类型属性都可以使用这种方式初始化
Class::Constructor(type *t1,type &t2,type t3...):t1(t1),t2(t2),t3(t3)...{}
使用构造函数定义对象
当我们声明过一个构造函数之后,我们可以有三种方式去调用它:
1,显式的调用
Student jack = Student("jack",99,98,97);
2,隐式的调用
Student jack("jack",99,98,97);
3,使用 new 运算符
Student *jack = new Student("jack",99,98,97);
上述3中方法的关键区别在于内存分配:前两种方式的对象将会被在栈中创建,第3中方式对象将会在堆中被创建
默认构造函数
当我们没有显式的在声明中添加构造方法时,编译器会默认提供一个空参列表且没有任何行为的默认构造方法,就像下面这样
Student(){}
但是当我们声明了自己的构造方法之后,编译器便不会再提供默认的构造方法了。
当我们想定义一个默认的构造器有两种方式:
1,给已有的构造函数的所有参数提供默认值
Student(std::string name,int chScore=0,int enScore=0,int mathScore=0);
2,定义一个没有参数的函数重载
Student(){}
由于每种类型的构造器只能声明一个,所以同时使用上述两种方式会报错。
注意:声明隐式方式调用空参构造方法不能使用括号,因为这是编译器会将这行代码解释为函数声明,比如:
Student jack;//available
Student jack();//invalidate
实例演示
1,在头文件student.h中声明类Student
//student.h -- Student class interface
//version 00
#ifndef STUDENT_H_
#define STUDENT_H_
#include <string>
class Student{ //class declaration
private:
std::string name;
int ch;
int en;
int math;
float average;
void count(){
average = (ch + en + math+0.0F)/3;
}
public:
Student();
Student(std::string name,int chScore,int enScore,int mathScore);
~Student();
void setName(std::string name);
void setChScore(int score);
void setEnScore(int score);
void setMathScore(int score);
void show();
};
#endif
2,在文件student.cpp中实现类方法
//student.cpp -- implementing the Student class
//version 00
#include "stdafx.h"
#include "student.h"
Student::Student(){
cout<<"您好呀! 新同学,你叫什么名字?"<<endl;
}
Student::Student(std::string n,int chScore,int enScore,int mathScore):name(n),ch(chScore),en(enScore),math(mathScore){
cout<<"您好呀! "<<name<<",很高兴见到你!"<<endl;
}
Student::~Student(){
cout<<"再见! "<<name<<"."<<endl;
}
void Student::setChScore(int score){
Student::ch = score;
}
void Student::setName(std::string n){
Student::name = n;
}
void Student::setEnScore(int score){
en = score;
}
void Student::setMathScore(int score){
math = score;
}
void Student::show(){
Student::count();
ios_base::fmtflags orig = cout.setf(ios_base::fixed,ios_base::floatfield);
std::streamsize prec = cout.precision(1);
cout<<name<<" 同学的语文成绩为"<<ch<<"分,数学成绩为"<<math<<"分,英语成绩为"<<en<<"分,平均成绩"<<average<<"分"<<endl;
cout.setf(orig,ios_base::floatfield);
}
3,在mian方法中调用
//visual studio 2010 --main program
#include "stdafx.h"
#include "student.h"
int _tmain(int argc, _TCHAR* argv[]){
Student *s1,s2,s3("Jack",90,80,70);
s1 = new Student("Sam",90,95,100);
s1->show();
s2 = Student("Sue",85,90,95);
s2.show();
s3.show();
s1 = new Student("Joe",91,92,93);
s1->show();
delete s1;
return 0;
}
运行结果
运行结果:
您好呀! 新同学,你叫什么名字?
您好呀! Jack,很高兴见到你!
您好呀! Sam,很高兴见到你!
Sam 同学的语文成绩为90分,数学成绩为100分,英语成绩为95分,平均成绩95.0分
您好呀! Sue,很高兴见到你!
再见! Sue.
Sue 同学的语文成绩为85分,数学成绩为95分,英语成绩为90分,平均成绩90.0分
Jack 同学的语文成绩为90分,数学成绩为70分,英语成绩为80分,平均成绩80.0分
您好呀! Joe,很高兴见到你!
Joe 同学的语文成绩为91分,数学成绩为93分,英语成绩为92分,平均成绩92.0分
再见! Joe.
再见! Jack.
再见! Sue.
请按任意键继续…