#include
using namespace std;
#define LEN 64
class Human {//类的首字母大写
public:
//2.构造函数类型
//②手动定义的默认构造函数√-又名默认构造函数
//定义对象时自动调用默认构造函数中的值
Human();//没有返回值也不能写返回值(void也不能写)
//③自定义的带参数(重载-同名)构造函数√-又名自定义构造函数
//=Human(string, int );
Human(string name, int age);
//④拷贝构造函数
//④手动定义的拷贝构造函数(只写一个)√;合成的拷贝构造函数×-会同步传值,不是一次简单的复印
//=Human(const Human& src);
Human(const Human& );
//④--拷贝构造函数的调用时刻
//④①函数形参为对象,实参对象为其赋值(引用为别名不赋值)
//④②函数返回值为对象,创建临时对象供返回(引用为别名不返回)
//④③对象(包括对象数组)初始化,拷贝对象给其初始值--注意为初始化,即定义时赋值
//⑤赋值构造函数--注意为定义后赋值
//⑤手动定义的赋值构造函数√;合成的赋值构造函数×-会同步传值,不是一次简单的复印
//等号运算符重载
Human&operator = (const Human & src);
void eat() {//若函数很简单且只用一二次可直接写;若多次调用则用内联函数inline
cout << "我在吃饭!" << endl;
}
void hobby();
void description() const;
// Human getYounger(const Human man1, const Human man2);因为类的功能的返回值不能为类,所有不能定义为类的功能,要在外部定义一个函数
string getName() const;
int getAge() const;//方法写作函数,public只有方法,故public中全部为函数
int getSalary();
const char* getAddr();
void setAddr(const char* newAddr);
private:
//①合成的默认构造函数×
int age = 18;//数据封装在内部,防止他人恶意篡改和隐私泄露(可内部选择不告知);类似库文件,可代码封装,只给头文件
string name;//内部数据不建议初始化
int salary;
//string addr时strcpy不能用,因string属c++,char*和strcpy属c
char* addr = NULL;//指针记得初始化
};
void Human::hobby() {
cout << "我在做自己喜欢的事情!" << endl;
}
string Human::getName() const{
return name;
}
int Human::getAge() const{
return age;
}
int Human::getSalary() {
return salary;
}
const char* Human::getAddr() {
return addr;
}
void Human::setAddr(const char* newAddr) {
if (!newAddr) return;
strcpy_s(addr, LEN, newAddr);
}
void Human::description() const{
cout << "年龄:" << age << "名字:" << name << "薪资:" << salary << "地址:" << addr << endl;
}
//---------②---------
Human::Human() {
cout << "调用手动定义的默认构造函数" << endl;
name = "默认名";//前面不要加类型,是调用数据成员而不是定义变量
age = 1;
salary = 11;
addr = new char[LEN];//记得分配内存空间
strcpy_s(addr, LEN, "China");
}
//---------③---------
Human::Human(string name, int age) {
cout << "调用自定义的带参数构造函数" << endl;
this->name = name;//this是一个特殊的指针,指向这个对象本身
this->age = age;
this->salary = 12;
addr = new char[LEN];//记得分配内存空间
strcpy_s(addr, LEN, "China");
}
//---------④---------
Human::Human(const Human& src) {//别名为src
cout << "调用手动定义的拷贝构造函数" << endl;
name = src.name;
age = src.age;
salary = src.salary;
addr = new char[LEN];//记得手动拷贝函数要分配内存空间
strcpy_s(addr, LEN, src.addr);
}
//---------④---------
void showMsg(const Human &man) {
cout << man.getName() << "的信息是:";
man.description();
}
//const Human& getYounger(const Human &man1, const Human &man2) {//0
//const Human getYounger(const Human man1, const Human man2) {//3
//每多一个引用符号,少一次拷贝构造函数的调用
//调用数=对象数
Human getYounger(const Human &man1, const Human &man2) {
if (man1.getAge() < man2.getAge()) {
return man1;
}
return man2;
}
//---------⑤---------
Human& Human::operator = (const Human & src){
name = src.name;
age = src.age;
salary = src.salary;
//动态内存视需要释放
//此处因下一步修改覆盖addr中的值,故释放原有内存
delete addr;
addr = new char[LEN];
//拷贝字符数组,不能直接赋值
//addr=src.addr;×-浅拷贝/位拷贝,只传递了字符数组首地址,即指向同一地址
strcpy_s(addr, LEN, src.addr);
return *this;//指针解引为对象,内容对应返回值为Human类对象的别名;返回自身,方便链式处理
}
int main() {
//1.访问对象
//①直接定义对象
Human h1;
h1.eat();
//h1.age;×-private在main中不可访问
//②指针指向对象
Human* p;
//p->hobby();×-使用了未初始化的局部变量,未指向地址.指针不能直接访问
p = &h1;
cout << "合成的默认构造函数:" <<"年龄:"<< p->getAge() << endl;//中断,提示p未被初始化;或打印出年龄是负值-因return age中的age未初始化-合成的默认构造函数:需将全部数据成员使用类内初始值才用
//---------②---------
cout << "手动定义的默认构造函数:" <<"姓名:"<< h1.getName() << endl;
Human h2;
cout << "手动定义的默认构造函数:" << "姓名:" << h2.getName() << endl;//默认名,不带参定义对象则其数据默认
//---------③---------
Human h3("带参名", 100);
cout << "自定义的带参构造函数:" << "姓名:" << h3.getName() << endl;
Human *p3 = &h3;
cout<< "自定义的带参构造函数:" << "薪资:" << p3->getSalary() << endl;
//---------④---------
//Human h4; h4=h3;则为调用赋值构造函数
Human h4 = h3; Human h5(h3);//完全相同
//---------浅拷贝/位拷贝(指向/占用同一块内存)---------
//=cout << h3.getAddr() << endl;//函数名=其返回值
//=cout << h4.getAddr() << endl;
h3.description(); h4.description();
h3.setAddr("美国");
//---------深拷贝(含手动拷贝函数声明和定义)---------
h3.description();h4.description();
//---------④①+④②---------
const Human h41("41", 19);//函数定义时不必定义const
const Human h42("42", 22);
getYounger(h41, h42);
cout << "-----------";
showMsg(h41);
//---------⑤---------
Human h51("51", 51);
Human h52;
h52 = h51;
showMsg(h52);
//system("pause");VS中自动暂停,按任意键后退出
return 0;
}
//对指针进行操作时永远要判断是否是空指针
#include
using namespace std;
//extern int Cnt;
class Human {
public:
Human();
Human(int, string);
Human(const Human&);
int getAge();
int getCnt();
static int getCNT();
void description();
private:
int age;
//const static int cnt=1;常静态,不能改变
static int cnt;//静态数据成员不能类内初始化
const string bloodType = "未知";//常量在C11可类内初始化
};
//const int Human::cnt = 1;const静态//若与初始化是不同,以类外赋值为准
//int Cnt = 0;全局
int Human::cnt = 0;//只有静态数据成员可以在类的外部定义,因为它不属于任何一个对象
//const string Human::bloodType = "未知";×
Human::Human() :bloodType("未知") {//string常量初始化方法,不能直接赋值;默认构造函数
age = 0;
//bloodType = "未知";×二进制“ = ”: 没有找到接受“const std::string”类型的左操作数的运算符(或没有可接受的转换)
//Cnt++;
cnt++;
}
Human::Human(int age, string bldType) :bloodType(bldType) {//自定义带参构造函数
this->age = age;
//Cnt++;
cnt++;
}
Human::Human(const Human& src) {//
age = src.age;
//Cnt++;
cnt++;
}
int Human::getAge() {
return age;
}
int Human::getCnt() {//非静态成员函数调用必须有对象
return cnt;
}
int Human::getCNT() {
//this->age = 10;×static成员函数因为可以类调用,所以可以没有特定对象
//age = 10;×非静态数据成员引用必须与特定对象相对,而static成员函数因为可以类调用,所以可以没有特定对象
//Human q1;q1.age = 10;//只可以调用已确定对象的非静态数据成员和静态数据成员
return cnt;//公用值,即静态数据成员
}
void Human::description() {
cout << "年龄为:" << age << "血型为:" << bloodType << endl;
}
int main() {
Human q1;
Human q2(2, "A");
Human q3 = q1;
cout << "------静态数据成员------" << endl;
//cout << "人数为:" << Cnt << endl;全局
//cout << "人数为:" << Human::getCnt() << endl;×-非静态成员必须和特定对象相对
cout << "人数为:" << q1.getCnt() << endl;//若成员函数为普通类型,则必须通过对象调用,不能通过类调用
cout << "------静态成员函数------" << endl;
cout << "人数为:" << q1.getCNT() << endl;
cout << "人数为:" << Human::getCNT() << endl;
cout << "------常量数据成员bloodType------" << endl;
q1.description();
q2.description();
return 0;
}
附: string类可直接赋值, 为深拷贝, 复制一份, 地址不同<-> char * 类直接赋值为指向同一地址, 浅拷贝
#include
using namespace std;
//string(c++)型可以直接赋值,且所在地址不同.相当于int型
int main() {
string s1 = "肉肉";
string s2 = s1;
cout << s2 << endl;//肉肉
cout << &s1 << endl;//&si≠&s2
cout << &s2 << endl;
return 0;
}
this用法: 不能指向类公有的静态数据成员
Human.h
#pragma once
#include
using namespace std;
//extern int Cnt;
class Human {
public:
Human();
Human(int);
Human(const Human&);
int getAge();
void description();
Human& getYounger(Human&);
Human* getOlder(Human*);
private:
int age;
};
Human.cpp
#include "this_Human.h"
Human::Human(){//常量初始化方法
age = 0;
}
//①形参同名:this->指向这个public函数调用的对象
//=Human::Human(int aAge) {age = aAge;}
Human::Human(int age){
this->age = age;
}
Human::Human(const Human& src) {
age = src.age;
}
int Human::getAge() {
return age;
}
void Human::description() {
cout << "年龄为:" << age << endl;
}
//②形参和返回值为引用:*this(只含一个参数即比较对象)-需要是public功能,不能是非class函数,因为要返回this
Human& Human::getYounger(Human& other) {
if (this->age < other.age) return *this;
return other;
}
//③形参和返回值为指针:this
Human* Human::getOlder(Human* other) {
if (this->age > other->age) return this;
return other;
}
main.cpp
#include "this_Human.h"
int main() {
Human h1(1);
Human h2(2);
(h1.getYounger(h2)).description();//1,类的.:结合方向从左到右
Human* p = &h1;
p->getOlder(&h2)->description();//2,指针->:结合方向从左到右
return 0;
}