2017-02-14 7 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 특성을 다시 정의합니다. 속성은 private이며 getter에 의해 반환됩니다. 이 같은 클래스의 모든 인스턴스에 대해 동일한 값을 반환하도록 내가) (클래스 멤버 함수를 함수 getTableName을 만들고 싶어

#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; 
}; 

: 여기에 하위 클래스 중 하나의 예로서 헤더 파일입니다 클래스의 인스턴스 없이도 호출 할 수 있습니다. 필자가 잘못하지 않았다면 헤더 파일에 함수 선언 앞에 키워드 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을 사용하여 해결책을 찾았습니다.

파일

#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.h 파일 persondb :

나를 위해 일한 해결책은 다음과 같다.

파일 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; 
} 
: 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입니다

-2

"상속 된 클래스 멤버 함수를 정적으로 만들 수있는 방법이 있습니까?" 아니요

2

상속 된 클래스 멤버 함수를 정적으로 만드는 방법이 있습니까?

수 없습니다. static 함수의 이름을 다른 것으로 변경하고 클래스에 맞는 것이면 일반 멤버 함수에서 사용할 수 있습니다.

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

virtualstatic는이 개 모순의 요구 사항을 나타냅니다.

static 기능은 클래스 수준이며 특정 클래스 인스턴스에 제약되지 않습니다.

virtual 기능은 인스턴스 수준이며 이와 같은 동작은 관련 개체에 의해 정의됩니다.

요구 사항을 다시 고려해야합니다.