如何定义从虚拟函数继承的静态函数

How to define a static function inherited from a virtual one?

本文关键字:函数 虚拟 继承 静态函数 何定义 定义      更新时间:2023-10-16

我正在使用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;
};

此课程由不同的子类继承。每个子类重新定义 *.cpp文件中分配不同值的tableName属性。该属性是私人的,由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();

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

编辑:如果我不能静态函数,那么如果没有类的实例,我该如何使私有属性在外部访问(并保持私有)?

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

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

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

virtualstatic表示2个矛盾的要求。

static函数是 class-level 构造,并且不受任何特定类实例的约束。

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

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

我使用了好奇的重复模板模式找到了解决方案。

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

文件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;
}

"是否有一种方法可以使继承的类成员函数静态?" no