2017-02-14 1 views
-4

私はちょっとしたアプリケーションにC++を使用しています。 仮想メソッドを持つ親クラスが1つあります。ヘッダファイルです。仮想関数から継承した静的関数を定義する方法は?

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属性を再定義します。属性はプライベートであり、ゲッターによって返されます。ここでは、子クラスの一つの例として ヘッダファイルです:

#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:関数を静的にすることができない場合、クラスのインスタンスなしでprivate属性を外部にアクセスできるようにするにはどうすればよいですか?

答えて

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 persondb.h

ファイル:私のために働いた

ソリューションは次のとおりです。

ファイル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

virtualおよびstaticは、2つの矛盾する要件を表します。

static機能はクラスレベルであり、特定のクラスインスタンスに制約されません。

virtual機能はインスタンスレベルであり、その動作は関連オブジェクトによって定義されます。

要件を再検討する必要があります。

関連する問題