2017-02-14 22 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; 
}; 

Этот класс унаследован различными дочерними классами. Каждый дочерний класс переопределяет атрибут tableName, назначая другое значение в файле * .cpp. Атрибут является закрытым и возвращается получателем. В качестве примера одного из дочерних классов здесь есть заголовочный файл:

#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(); 

Есть ли способ, чтобы сделать наследуются функция члена класса статической?

EDIT: Если я не могу сделать статическую функцию, как я могу сделать доступным внешний атрибут снаружи без экземпляра класса (и держать его закрытым)?

ответ

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 файла.каст

#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

«Есть ли способ сделать функцию унаследованного класса членом статической?» No

2

Есть ли способ сделать функцию унаследованного класса членом статической?

Вы не можете. Вы можете переименовать функцию static на что-то еще и использовать ее из регулярной функции-члена, если это имеет смысл для вашего класса.

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

virtual и static представляют 2 требования противореча.

static function is class-level Конструкция и не ограничена каким-либо конкретным экземпляром класса.

virtual Функция является фактом уровня и поэтому его поведение определяется соответствующим объектом.

Вам необходимо будет пересмотреть свои требования.

 Смежные вопросы

  • Нет связанных вопросов^_^