【问题标题】:Inheriting static variable in classes?在类中继承静态变量?
【发布时间】:2020-10-18 01:29:43
【问题描述】:

给定一个名为 Job 的抽象类和其他继承它的类,如 TeacherWorker 等......

我希望这些类继承静态变量之类的东西-我的意思是,因为根据我的阅读,它不允许继承静态变量-对于Job(如Salary),每个类具有不同的值,我该怎么做?

到目前为止,Teacher 的 c'tor 中,我为每个名为 salary 的对象创建了一个局部变量,使其等于 100,但这似乎并不聪明,因为根据我的工作,所有老师都有相同的薪水。


例如:

class Job{
    int salary;
    std::string tag;
public:
    Job(int salary,std::string tag;) : salary(salary), tag(tag)
    {}
};

class Teacher: public Job{
public:
    Teacher(std::string tag) : Job(100,tag){}
};

class Worker: public Job{
    Worker(std::string tag) : Job(200,tag){}
};

每个工人的薪水=100,但我希望这与班级工人有关,而不是与每个对象有关。 (我可以将其定义为每个类的静态值,但在 100 个类中声明相同的静态值并继承一个具有该静态值的类似乎并不明智)

【问题讨论】:

  • 您能否为您当前的方法添加一些代码,以及您希望它如何工作?
  • @MikaelH 正在努力
  • 直到现在,在教师的 c'tor 中,我为每个名为salary 的对象创建了一个局部变量,使其等于 100,但这似乎并不聪明,因为所有教师都有根据我的工作,工资是一样的。 相反,这是完全正确的。您发布的代码没有任何问题(而且,有一天,您将能够给个别教师加薪 :)
  • @PaulSanders 为什么每个工人都应该有一个名为 Salary 的变量,其值为 200,而 所有 工人都可以共享它
  • @AdrianMole 或者那些禁止使用STL的...

标签: c++ class c++11 inheritance static


【解决方案1】:

我犹豫发布这个答案,因为我认为发布的代码很好,但如果你真的想消除 salary 变量,那么你可以这样做:

class Job
{
    ...
    virtual int GetSalary () = 0;
};

class Teacher : public Job
{
    ...
    int GetSalary () override { return 100; }
};

class Worker : public Job
{
    ...
    int GetSalary () override { return 200; }
};

可以使用类似的方案来消除tag(为此,实际上可能需要这种方法)。

【讨论】:

    【解决方案2】:

    您也可以使用模板,它们在编译时进行评估,因此您不会有性能开销:

    template <int Salary>
    class Job{
        std::string tag;
    public:
        static const int salary = Salary;
    
        Job(std::string tag) : tag(std::move(tag)) {
    
        }
    };
    
    class Teacher: public Job<100>{
    public:
        Teacher(std::string tag) : Job<100>(std::move(tag)) {
    
        }
    };
    
    class Worker: public Job<200>{
        Worker(std::string tag) : Job<200>(std::move(tag)) {
            
        }
    };
    

    您可以从普通的Teacher::salaryWorker::salaryJob&lt;N&gt;::salary 等处获得薪水。

    【讨论】:

    • 什么是std::move 为什么不是tag(tag)?
    • @BigSur tag(tag) 为构造函数内部的 tag 参数创建了一个无用的副本。 std::move 将参数转换为右值引用,以便它的值可以从字面上移动到另一个位置(这里,它是一个成员变量)并避免任何复制。在此过程中,原始位置的值(即参数tag)变为无效。
    • 用这种方法你不再得到一个通用的基类,这似乎是 OP 的目标之一与初始代码。
    【解决方案3】:

    我不确定这是否更多 software design。不管怎样,我会给你反馈当前的设计和你可以做什么(仍然使用公共继承)。

    您当前拥有的代码很好。它是灵活的,因为您可以实际上为每个对象设置特定的薪水。

    但是,当然,您要为灵活性付出代价 - 对于每个对象,您可能会有一个不必要的成员,因为它应该已经被类型知道了。

    如果您希望灵活地拥有具有相同薪水的班级和具有专业薪水的班级,您可以稍微扩展您的层次结构:

    class IJob{
        public:
        virtual double getSalary() = 0;
    };
    
    // Teachers always have the same salary
    class Teacher: public IJob{
        static constexpr double salary = 200; // named constant, not strictly necessary. But it can make it more readable.
    public:
        double getSalary virtual() { return salary; }
    };
    
    // Worker always have the same salary
    class Worker : public IJob{
        static constexpr double salary = 100;
    public:
        double getSalary virtual() { return salary; }
    };
    
    // A base class for workers having different salaries
    class SalarizedJob : public IJob
        double salary;
    public:
        SalarizedJob(double salary) : salary(salary) {}
        double getSalary() override { return salary; };
    };
    
    // Greedy bankers always want more salary than their coworker
    class Banker : public SalarizedJob
    {
        public:
        Banker(double salary) : SalarizedJob(salary) {}
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-24
      • 2011-08-05
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-10
      • 2017-01-10
      相关资源
      最近更新 更多