【问题标题】:How to define a static function inherited from a virtual one?如何定义从虚拟函数继承的静态函数?
【发布时间】:2017-07-03 10:44:57
【问题描述】:

我将 C++ 用于一个小应用程序。 我有一个具有虚拟方法的父类。这是头文件。

class personDB:public person
{
public:
    unsigned int id;
public:
    personDB();
    personDB(QString dbName, QString dbSurname);
    personDB(QString dbName, QString dbSurname, unsigned int dbid);
    personDB(std::string dbName, std::string dbSurname, unsigned int dbid);
    virtual std::string getTableName();
    unsigned int getID(void);
    void setID(unsigned int myID);
private:
    static const std::string tableName;
};

这个类被不同的子类继承。每个子类重新定义 tableName 属性,在 *.cpp 文件中分配不同的值。该属性是私有的,由 getter 返回。 作为子类之一的示例是头文件:

#include "persondb.h"
class ScriptBy : public personDB
{
public:
    ScriptBy();
    ScriptBy(QString dbName, QString dbSurname);
    ScriptBy(QString dbName, QString dbSurname, unsigned int dbid);
    std::string getTableName();
protected:
    static const std::string tableName;
};

我想让函数 getTableName() 成为类成员函数,以便它为同一类的所有实例返回相同的值,并且即使没有该类的实例也可以调用。如果我没记错的话,这应该通过将关键字static 放在头文件中的函数声明之前来完成。但是,当我尝试以这种方式编译时,它给了我一个与父类中的函数被声明为虚拟的事实相关的错误。 我得到的错误是这样的:

In file included from ../../singlestory.h:4:0,
                 from ../../volume.h:5,
                 from ../../dbinterface.h:8,
                 from ../../dbinterface.cpp:1:
../../scriptby.h:12:24: error: ‘static std::__cxx11::string ScriptBy::getTableName()’ cannot be declared
     static std::string getTableName();
                        ^
In file included from ../../dbinterface.h:7:0,
                 from ../../dbinterface.cpp:1:
../../persondb.h:15:25: error:   since ‘virtual std::__cxx11::string personDB::getTableName()’ declared in base class
     virtual std::string getTableName();

有没有办法让继承的类成员函数变成静态的?

编辑:如果我不能将函数设为静态,如何在没有类实例的情况下使私有属性在外部可访问(并保持私有)?

【问题讨论】:

    标签: c++ inheritance static virtual-functions


    【解决方案1】:

    “有没有办法让继承的类成员函数变成静态的?”没有

    【讨论】:

      【解决方案2】:

      有没有办法让继承的类成员函数变成静态的?

      你不能。如果这对您的类有意义,您可以将 static 函数重命名为其他名称并从常规成员函数中使用它。

      class ScriptBy : public personDB
      {
          virtual std::string getTableName() { return getTableNameStatic(); }
          static std::string getTableNameStatic();
      };
      

      【讨论】:

        【解决方案3】:

        virtualstatic 代表 2 个相互矛盾的要求。

        static 函数是一个类级构造,不受任何特定类实例的限制。

        virtual 函数是一个实例级构造,因此它的行为由相关对象定义。

        您需要重新考虑您的要求。

        【讨论】:

          【解决方案4】:

          我找到了使用Curiously Recurring template pattern 的解决方案。

          对我有用的解决方案如下:

          文件 persondb.h

          #ifndef PERSONDB_H
          #define PERSONDB_H
          
          #include "person.h"
          #include"common.h"
          class personDB:public person
          {
          public:
              using person::person;
              personDB(QString dbName, QString dbSurname, unsigned int dbid);
              personDB(std::string dbName, std::string dbSurname, unsigned int dbid);
              unsigned int getID(void);
              void setID(unsigned int myID);
          protected:
              unsigned int id;
          };
          
          /* Curiously recurring template paradigm */
          template<class Derived>
          class PersonDBX: public virtual personDB
          {
              using personDB::personDB;
          protected:
              static const std::string tableName;
              static const personRelationTable personIDtable;
          public:
              static std::string static_getTableName(){ return tableName; }
              std::string getTableName(){return tableName;}
              static std::string static_getIDTableName(){ return personIDtable.tableName; }
              std::string getIDTableName(){return personIDtable.tableName;}
          
              static std::string static_getCol1TableID(){ return personIDtable.col1; }
              std::string getCol1TableID(){return personIDtable.col1;}
          
              static std::string static_getCol2TableID(){ return personIDtable.col2; }
              std::string getCol2TableID(){return personIDtable.col2;}
          
          
          
              personDBX(QString dbName, QString dbSurname, unsigned int dbid):personDB(dbName, dbSurname)
              {
                  id = dbid;
              }
              PersonDBX():personDB(){;}
          
              PersonDBX(QString dbName, QString dbSurname):personDB(dbName, dbSurname){;}
          };
          template<class Derived> const std::string PersonDBX<Derived>::tableName = "Null";
          template<class Derived> const personRelationTable PersonDBX<Derived>::personIDtable = {"Null", "Null", "Null"};
          
          #endif // PERSONDB_H
          

          文件 persondb.cpp

          #include "persondb.h"
          
          personDB::personDB(QString dbName, QString dbSurname, unsigned int dbid):person(dbName, dbSurname){
          
              id = dbid;
          }
          
          personDB::personDB(std::string dbName, std::string dbSurname,
                             unsigned int dbid):person(dbName, dbSurname){
          
              id = dbid;
          }
          
          unsigned int personDB::getID(void){
              return id;
          }
          
          void personDB::setID(unsigned int myID)
          {
              id = myID;
          }
          

          子类是scriptby:

          文件 scriptby.h

          #ifndef SCRIPT_H
          #define SCRIPT_H
          
          #include "persondb.h"
          
          class ScriptBy : public PersonDBX<ScriptBy>
          {
          public:
              using PersonDBX::PersonDBX;
              ScriptBy(QString dbName, QString dbSurname, unsigned int dbid);
          protected:
          };
          
          #endif // SCRIPT_H
          

          文件 scriptby.cpp

          #include "scriptby.h"
          #include <iostream>
          #include <globals.h>
          
          template<> const std::string PersonDBX<ScriptBy>::tableName = "ScriptBy";
          template<> const personRelationTable PersonDBX<ScriptBy>::personIDtable = {"Story_ScriptBy","StoryID", "ScriptByID"};
          
          ScriptBy::ScriptBy(QString dbName, QString dbSurname, unsigned int dbid):PersonDBX(dbName, dbSurname)
          {
              id = dbid;
          }
          

          【讨论】:

            猜你喜欢
            • 2015-06-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-08-14
            • 1970-01-01
            • 2013-07-24
            相关资源
            最近更新 更多