2017-02-14 44 views
-4

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

有没有一种方法,使继承的类成员函数的静态?

编辑:如果我不能使该函数静态,我怎么可以使私人属性外面访问没有类的实例(并保持私人)?

回答

0

我找到了一个使用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; 
} 
-2

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

2

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

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

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

virtualstatic表示2级矛盾的要求。

static功能是一个类级结构,并没有限制到任何特定的类实例。

virtual功能是实例级构造,因此它的行为由相关对象定义。

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