题目:13.1
以下面的类声明为基础:
class Cd//表示CD盘
{
private:
char performers[50];
char label[20];
int selections; //选择次数
double playtime;
public:
Cd(char* s1, char* s2, int n, double x);//有参构造
Cd(const Cd& d);//拷贝构造
Cd();//无参构造
~Cd();//虚构函数
void Report() const;
Cd& operator=(const Cd& d);//重载等号操作
};
派生出一个Classic类,并添加一组char成员,用于存储指出CD中主 要作品的字符串。修改上述声明,使基类的所有函数都是虚的。如果上 述定义声明的某个方法并不需要,则请删除它。使用下面的程序测试您 的产品:
#pragma once
#include<iostream>
using namespace std;
//修改上述声明,使基类的所有函数都是虚的。
class CD//表示CD盘
{
private:
char performers[50];
char label[20];
int selections; //选择次数
double playtime;
public:
CD(const char* s1, const char* s2, int n, double x);//有参构造
CD(const CD& d);//拷贝构造
CD();//无参构造
~CD();//析构函数
//虚函数,允许被重写
virtual void Report() const;//打印信息
virtual CD& operator=(const CD& d);//重载等号操作
};
#include "CD.h"
CD::CD(const char* s1, const char* s2, int n, double x)//有参构造
{
strcpy_s(this->performers, strlen(s1)+1, s1);
strcpy_s(this->label, strlen(s2)+1, s2);
this->selections = n;
this->playtime = x;
}
CD::CD(const CD& d)//拷贝构造
{
strcpy_s(this->performers, strlen(d.performers), d.performers);
strcpy_s(this->label, strlen(d.label), d.label);
this->selections = d.selections;
this->playtime = d.playtime;
}
CD::CD()//无参构造
{
cout << "CD无参构造!!!" << endl;
}
CD::~CD()//析构函数
{
cout << "CD析构函数!!!" << endl;
}
//虚函数,允许被重写
void CD::Report() const
{
std::cout << "Performers: " << performers << std::endl;
std::cout << "Label: " << label << std::endl;
std::cout << "Selections: " << selections << std::endl;
std::cout << "Playtime: " << playtime << std::endl;
}
CD& CD::operator=(const CD& d)//重载等号操作
{
//本质也是拷贝
strcpy_s(this->performers, strlen(d.performers), d.performers);
strcpy_s(this->label, strlen(d.label), d.label);
this->selections = d.selections;
this->playtime = d.playtime;
return *this;
}
#pragma once
#include"CD.h"
class Classic:public CD
{
private:
char mainfile[20];
public:
Classic(const char* s1, const char* s2,const char*s3, int n, double x);
void Report() const;//打印信息
CD& operator=(const CD& d);//重载等号操作
};
#include "Classic.h"
Classic::Classic(const char* s1, const char* s2,const char*s3, int n, double x):CD(s1, s2, n, x)
{
strcpy_s(mainfile,strlen(s3)+1, s3);
}
void Classic::Report() const//打印信息
{
cout << "mainfile:" << this->mainfile << endl;
}
CD& Classic::operator=(const CD& d)//重载等号操作
{
return*this;
}
问题1: 基类的函数都是虚函数,意思是派生类要使用的话必须要重写函数吗
是的,基类的虚函数是为了让派生类能够根据自己的需求来重新实现这些函数。派生类可以选择性地重写基类的虚函数,以实现特定的功能或行为。如果派生类不重写基类的虚函数,那么将会直接使用基类的虚函数。因此,基类的虚函数可以作为接口,提供给派生类进行重写或扩展。
问题2: 只有虚函数才和纯虚函数才允许重写吗
不完全正确。虚函数和纯虚函数都可以被派生类重写。虚函数是通过在基类中使用关键字
virtual
来声明的,派生类可以选择性地重写这些虚函数。而纯虚函数是在基类中使用关键字virtual
和= 0
来声明的,派生类必须实现这些纯虚函数,否则派生类也会成为抽象类。因此,虚函数和纯虚函数都可以被派生类重写,只是对于纯虚函数来说,派生类必须实现它们。
问题3:等号运算符的重载,本质上也就是一种拷贝操作
是的,赋值操作符重载本质上也是一种拷贝操作。当使用赋值操作符将一个对象赋值给另一个对象时,实际上是将对象的数据成员逐个拷贝到另一个对象中。这种拷贝操作会涉及到浅拷贝和深拷贝的问题,具体取决于类中数据成员的类型和内存管理方式。在赋值操作符重载函数中,需要确保正确地拷贝对象的数据成员,以避免出现浅拷贝导致的问题。