1.给这个类提供实现,并编写程序使用所有成员函数
char name[20]; char* hobby; double weight; public: Cow(); Cow(const char* nm,const char* ho,double wt); Cow(const Cow& c); ~Cow(); Cow& operator= (const Cow& c); void showcow() const; };
源代码文件如下:
#include"cow.h"
#include<iostream>
#include<cstring>
Cow::Cow()
{
strcpy(name,"Jeff");
hobby = new char[3];
strcpy(hobby,"No");
weight = 100;
}
Cow::Cow(const char* nm,const char* ho,double wt)
{
strcpy(name,nm);
hobby = new char[strlen(ho),+1];
strcpy(hobby,ho);
weight = wt;
}
Cow::Cow(const Cow& c)
{
strcpy(name,c.name);
hobby = new char[strlen(c.hobby)+1];
strcpy(hobby,c.hobby);
weight = c.weight;
}
Cow::~Cow()
{
std::cout<<name<<" has delete"<<std::endl;
delete [] hobby;
}
Cow& Cow::operator=(const Cow& c)
{
strcpy(name,c.name);
hobby = new char[strlen(c.hobby)+1];
strcpy(hobby,c.hobby);
weight = c.weight;
return *this;
}
void Cow::showcow() const
{
using std::cout;
using std::endl;
cout<<"Name:\t"<<name<<endl;
cout<<"Hobby:\t"<<hobby<<endl;
cout<<"Weight:\t"<<weight<<endl;
}
程序解析:
- hobby是字符串指针,你不能直接用strcpy(hobby,"xxx")或者hobby = ho等,因为你用strcpy的话是把“xxx”复制到hobby所指的内存地址,此时hobby没有指向什么地方。赋值运算符=ho也是同样的道理。如果你hobby = &("xx") 就是将非const指向const了。
所以最好就是new 开辟内存空间。- 析构函数要delete []
- 重载赋值运算符要返回this指针指向的对象
#include"cow.h"
#include<iostream>
int main()
{
using std::cout;
using std::endl;
Cow c1;
Cow c2("Jack","Doing sports",120.0);
Cow c3(c2);
Cow c4;
c4 = c3;
cout<<"C1:\n";
c1.showcow();
cout<<"C2:\n";
c2.showcow();
cout<<"C3:\n";
c3.showcow();
cout<<"C4:\n";
c4.showcow();
return 0;
}
结果:
题目
类声明文件
#ifndef PORT_H_
#define PORT_H_
#include<iostream>
using namespace std;
class Port
{
private:
char* brand;
char style[20];
int bottles;
public:
Port(const char* br ="none",const char* st ="none",int b=0);
Port(const Port& p);
virtual ~Port() {delete [] brand;}
Port& operator=(const Port& p);
Port& operator+=(int b);
Port& operator-=(int b);
int BottleCount () const {return bottles;}
virtual void Show() const;
friend ostream& operator<<(ostream& os, const Port& p);
};
class VPort : public Port
{
private:
char* nickname;
int year;
public:
VPort();
VPort(const char* br,const char* st,int b,const char* nn,int y);
VPort(const VPort& vp);
~VPort(){delete [] nickname;}
VPort& operator=(const VPort& vp);
void Show() const;
friend ostream& operator<<(ostream& os,const VPort& vp);
};
#endif
程序解析:
- 为何没有将运算符重载声明为虚函数呢:
因为参数不一样,特征不同,没有必要声明为虚函数- operator<<为友元因为调用对象是ostream类
源代码文件
#include"port.h"
#include<cstring>
Port::Port(const char* br, const char* st, int b)
{
brand = new char[strlen(br)+1];
strcpy(brand,br);
strcpy(style,st);
bottles = b;
}
Port::Port(const Port& p)
{
brand = new char[strlen(p.brand)+1];
strcpy(brand,p.brand);
strcpy(style,p.style);
bottles = p.bottles;
}
Port& Port::operator=(const Port& p)
{
if(this == &p)
return *this;
delete [] brand;
brand = new char[strlen(p.brand)+1];
strcpy(brand,p.brand);
memset(style,'\0',20);
strcpy(style,p.style);
bottles = p.bottles;
return *this;
}
Port& Port::operator+=(int b)
{
bottles += b;
return *this;
}
Port& Port::operator-=(int b)
{
bottles -= b;
return *this;
}
void Port::Show() const
{
cout<<"Brand: "<<brand<<"\n"
<<"Kind: "<<style<<endl<<"Bottles: "
<<bottles<<endl;
}
ostream& operator<<(ostream& os,const Port& p)
{
os<<p.brand<<", "<<p.style<<", "<<p.bottles<<"\n";
return os;
}
VPort::VPort():Port()
{
nickname = new char[7];
strcpy(nickname,"nobody");
year = 0;
}
VPort::VPort(const char* br,const char* st ,int b, const char* nn, int y): Port(br,st,b)
{
nickname = new char[strlen(nn)+1];
strcpy(nickname,nn);
year = y;
}
VPort::VPort(const VPort& vp):Port(vp)
{
nickname = new char[strlen(vp.nickname)+1];
strcpy(nickname,vp.nickname);
year = vp.year;
}
VPort& VPort::operator=(const VPort& vp)
{
if(this == &vp)
return *this;
Port::operator=(vp);
delete [] nickname;
nickname = new char[strlen(vp.nickname)+1];
strcpy(nickname,vp.nickname);
year = vp.year;
}
void VPort::Show() const
{
Port::Show();
cout<<"Nickname: "<<nickname<<endl
<<"Years: "<<year<<endl;
}
ostream& operator<<(ostream& os, const VPort& vp)
{
operator<<(os,(const Port& )vp)<<vp.nickname<<", "<<vp.year<<"\n";
return os;
}
程序解析:
- 主要讲讲派生类成员函数调用基类成员函数:
比如运算符重载=函数: 调用基类重载=运算符Port::operator=(vp)
,
首先,调用对象是this,所以this指向返回的对象引用。
其次,实参为vp,是基类引用,重载函数根据这个特征来使用不同的函数。- 重载<<运算符,因为是友元函数,所以也是多态函数,利用强制类型转换(类型要相同比如const转换为const)可以使派生类引用变为基类引用,从而使用基类友元重载运算符<<.