lisz-works

技術と興味の集合体

C++で親の親クラスの関数にアクセスできない?「error: ‘void Class::Function()’ is inaccessible」の解決方法

【スポンサーリンク】

プログラムのソースコード

「CA<-[継承]--CB<--[継承]--CC」という構成でクラスを作りました。

するとCCからCAの関数がアクセスできず

「error: ‘void Class::Function()’ is inaccessible」

というエラーが吐かれてしまいました。

おじいちゃん、なんで使わせてくれないの!

ソース

テスト用なのでクラスは全てヘッダに処理まで記述してしまいました。

CA.hpp

#if !defined(__CA_HPP__)
#define __CA_HPP__

#include "iostream"
using namespace std;

class CA
{
public:
    CA(){}
    ~CA(){}
    virtual void show()
    {
        cout << "CA" << endl;
    }
    void view() {
        cout << "caview" << endl;
    }
};
#endif // __CA_HPP__

CB.hpp

#if !defined(__CB_HPP__)
#define __CB_HPP__

#include "CA.hpp"

using namespace std;

class CB : CA
{
public:
    CB(){}
    ~CB(){}
};
#endif // __CB_HPP__

CC.hpp

#if !defined(__CC_HPP__)
#define __CC_HPP__

#include "iostream"
using namespace std;
#include "CB.hpp"

class CC : public CB
{
public:
    CC(){
        view();
    }
    ~CC(){}
};
#endif // __CC_HPP__

main

#include "CC.hpp"

int main(void)
{
    CC* c = new CC();

    return 0;
}

エラー

それぞれのクラスは

CA<-[継承]--CB<--[継承]--CC

のように継承しているはずなのに、CAの持っている関数がCCから見えない……

というようなエラーが出ました。

$ make all
g++ -O3 -mtune=native -march=native -mfpmath=both -g -Wall -Wextra -std=c++11 -o app main.cpp ClassX.o ClassA.o ClassB.o Test.o
In file included from CB.hpp:5:0,
                 from CC.hpp:6,
                 from main.cpp:13:
CA.hpp: In constructor ‘CC::CC()’:
CA.hpp:18:10: error: ‘void CA::view()’ is inaccessible
     void view() {
          ^
In file included from main.cpp:13:0:
CC.hpp:23:5: error: within this context
     view();
     ^
In file included from CB.hpp:5:0,
                 from CC.hpp:6,
                 from main.cpp:13:
CA.hpp:18:10: error: ‘void CA::view()’ is inaccessible
     void view() {
          ^
In file included from main.cpp:13:0:
CC.hpp:23:10: error: within this context
     view();
          ^
CC.hpp:23:10: error: ‘CA’ is not an accessible base of ‘CC’
main.cpp: In function ‘int main()’:
main.cpp:26:8: error: ‘class CC’ has no member named ‘show’
     c->show();
        ^
Makefile:22: ターゲット 'main' のレシピで失敗しました
make: *** [main] エラー 1

解決方法

色々やってる中、ふと気が付き解決しました。

継承するクラスのアクセス修飾子が原因だった!

CBでの継承のところが

class CB :  public CA
{}

としなければならないところを

class CB :  CA
{}

とpublicなしで継承していました……

コレだと恐らくCBの子クラスからは、publicではないCAの持ち物が見えない状態になっていたのでしょうね……

publicをつけてあげることで、問題なくCBでもCAの関数を実行することができました!

パット見分かりづらいのと、他の言語での継承はpublicとか指定していなかった気がするので、どうもこの辺りは慣れるしかないですねぇ……

参考

コチラを参考にしました。ありがとうございました!

stackoverflow.com

あとがき

「error: ‘void Class::Function()’ is inaccessible」で、親の親クラスの関数にアクセスできない?の解決方法でした!

C#やJavaとは違った構文が必要なので、慣れるまで同じことが起きかねないですね……

とはいえ覚えるか調べるかして、解決すれば問題ないので、参考になれば嬉しいです!