zoukankan      html  css  js  c++  java
  • 继承和构造函数语法造成的一个bug

    • 出错误的代码
      开发环境: visual studio 2017 社区版
    #include "pch.h"
    #include <iostream>
    #include <string>
    #include <list>
    using namespace std;
    
    //公司类 抽象类或接口
    class Company
    {
    public:
    	Company() {}
    	Company(string str)
    		:name(str) {}
    	virtual void Add(Company* c) = 0;  //增加
    	virtual void Remove(Company* c) = 0;  //移除
    	virtual void Display(int depth) = 0;  //显示
    	virtual void LineOfDuty() = 0;  //履行职责  
    	inline bool operator==(const Company& company) const
    	{
    		return this->name == company.name;
    	}
    protected:
    	string name;
    };
    
    class ConcreteCompany : public Company
    {
    public:
    	ConcreteCompany(string name) : Company(name)
    	{
    		children = new list<Company*>;
    	}
    	void Add(Company* c) override
    	{
    		children->push_back(c);
    	}
    	void Remove(Company* c) override  //删除子节点
    	{
    
    		for (list<Company*>::iterator it = children->begin(); it != children->end(); ++it)
    		{
    			if (*(*it) == *c)
    			{
    				children->erase(it);
    				break;
    			}
    		}
    	}
    	void Display(int depth) override  //显示
    	{
    		for (int ix = 0; ix < depth; ++ix)
    		{
    			cout << "-";
    		}
    		cout << this->name << endl;
    		for (list<Company*>::iterator it = children->begin(); it != children->end(); ++it)
    		{
    			(*it)->Display(depth + 2);
    		}
    	}
    	virtual void LineOfDuty() override  //履行职责
    	{
    		for (list<Company*>::iterator it = children->begin(); it != children->end(); ++it)
    		{
    			(*it)->LineOfDuty();
    		}
    	}
    private:
    	list<Company*>* children;
    };
    
    //人力资源部 树叶节点
    class HRDepartment : public Company
    {
    public:
    	HRDepartment(string str) : Company(name) {}
    	void Add(Company* c) override  //增加
    	{
    
    	}
    	void Remove(Company* c) override  //移除
    	{
    
    	}
    	void Display(int depth) override  //显示
    	{
    		for (int ix = 0; ix < depth; ++ix)
    		{
    			cout << "-";
    		}
    		cout << name << endl;
    	}
    	void LineOfDuty() override  //履行职责  
    	{
    		cout << this->name << " 员工招聘培训管理" << endl;
    	}
    };
    
    class FinanceDepartment : public Company
    {
    public:
    	
    	FinanceDepartment(string str) : Company(name) {}
    	void Add(Company* c) override  //增加
    	{
    
    	}
    	void Remove(Company* c) override  //移除
    	{
    
    	}
    	void Display(int depth) override  //显示
    	{
    		for (int ix = 0; ix < depth; ++ix)
    		{
    			cout << "-";
    		}
    		cout << name << endl;
    	}
    	void LineOfDuty() override  //履行职责  
    	{
    		cout << this->name << " 公司财务收支管理" << endl;
    	}
    };
    
    int main()
    {
    	Company* root = new ConcreteCompany("北京总公司");
    	root->Add(new HRDepartment("总公司人力资源部"));
    	root->Add(new FinanceDepartment("总公司财务部"));
    
    	ConcreteCompany* comp = new ConcreteCompany("上海华东分公司");
    	comp->Add(new HRDepartment("华东分公司人力资源部"));
    	comp->Add(new FinanceDepartment("华东分公司财务部"));
    	root->Add(comp);
    
    	ConcreteCompany* comp1 = new ConcreteCompany("南京办事处");
    	comp1->Add(new HRDepartment("南京办事处人力资源部"));
    	comp1->Add(new FinanceDepartment("南京办事处财务部"));
    	comp->Add(comp1);
    
    	ConcreteCompany* comp2 = new ConcreteCompany("杭州办事处");
    	comp2->Add(new HRDepartment("杭州办事处人力资源部"));
    	comp2->Add(new FinanceDepartment("杭州办事处财务部"));
    	comp->Add(comp2);
    
    	cout << "
    结构图" << endl;
    	root->Display(1);
    
    	cout << "
    职责:" << endl;
    	root->LineOfDuty();
    
    	return 0;
    }
    
    

    编译上述代码,VS2017提示错误

    一开始这个错误让我百思不得其解,因此将同样的代码放到Linux下编译调试。g++提示的错误如下:

    • 错误的解决
      经过排查发现,错误出现在下面这两行代码
    HRDepartment(string str) : Company(name) {}
    FinanceDepartment(string str) : Company(name) {}
    

    其中HRDepartment类和FinanceDepartment类均是继承自Company类,这两个类的构造函数初始化Company类中的成员name。正确的写法应该是

    HRDepartment(string str) : Company(str) {}
    FinanceDepartment(string str) : Company(str) {}
    

    三 知识补充

    • 派生类不能直接访问基类的私有成员,而必须通过基类方法进行访问。具体的说,派生类构造函数必须使用基类构造函数
    • 创建派生对象时,程序首先创建基类对象,这意味着基类对象应当在程序进入派生类构造函数之前被创建。C++使用成员初始化列表语法来完成这种工作。
    • 看下面一个例子
    class TableTennisPlayer
    {
    private:
    	string firstname;
    	string lastname;
    	bool hasTable;
    public:
    	TableTennisPlayer(const string &fn = "none",
    		const string &ln = "none", bool ht = false);
    };
    //基类的构造函数
    TableTennisPlayer::TableTennisPlayer(const string & fn, const string & ln, bool ht)
    	:firstname(fn),lastname(ln),hasTable(ht)
    {
    
    }
    
    class RatedPlayer : public TableTennisPlayer
    {
    public:
    	RatedPlayer(unsigned int r = 0, const string& fn = "none",
    		const string& ln = "none", bool ht = false);
    private:
    	unsigned int rating; //派生类需要一个数据成员存储比分
    };
    //子类的构造函数
    RatedPlayer::RatedPlayer(unsigned int r, const string & fn, const string & ln, bool ht)
    	:TableTennisPlayer(fn,ln,ht)
    {
    	this->rating = r;
    }
    
    int main()
    {
    	return 0;
    }
    

    先看RatedPlayer的一个构造函数

    //子类的构造函数
    RatedPlayer::RatedPlayer(unsigned int r, const string & fn, const string & ln, bool ht)
    	:TableTennisPlayer(fn,ln,ht)
    {
    	this->rating = r;
    }
    

    其中TableTennisPlayer(fn,ln,ht)是成员初始化列表,它是可执行的代码,调用TableTennisPlayer构造函数。例如,程序中包含以下声明

    RatedPlayer rplayerrl(1140,"Mallory","Duck",true);
    

    则RatedPlayer 构造函数将把实参”Mallory","Duck",true赋给形参fn,ln,ht,然后将这些参数作为实参传递给TableTennisPlayer(父类)的构造函数,后者将创建一个嵌套TableTennisPlayer对象,并将数据“Mallory","Duck",true存储在该对象中。然后,程序进入RatedPlayer(子类)构造函数体,完成RatedPlayer 对象的创建,并将参数r的值赋为rating成员。可以参考下图。

    • 将参数传递给基类构造函数
  • 相关阅读:
    分页 工具类 前后台代码 Java JavaScript (ajax) 实现 讲解
    java 对小数位的处理 BigDecimal DecimalFormat 常用操作 浅解
    事务 锁 悲观锁 乐观锁 概念 应用场景 使用方式 小记
    多项目使用同一个zookeeper,遇到的坑
    java线程关键字之volatile
    数据库事务
    Web.xml配置详解之context-param
    WINDOWS上KAFKA运行环境安装
    hibernate 之session学习
    windows 安装hadoop
  • 原文地址:https://www.cnblogs.com/Manual-Linux/p/11137025.html
Copyright © 2011-2022 走看看