Rainbow Engine

IT技術を分かりやすく簡潔にまとめることによる学習の効率化、また日常の気付きを記録に残すことを目指します。

C++

C++で「静的でないメンバー参照は特定のオブジェクトを基準とする相対参照である必要があります」エラーが出た時の対処

投稿日:2021年9月14日 更新日:

 

<目次>

(1) C++で「静的でないメンバー参照は特定のオブジェクトを基準とする相対参照である必要があります」エラーが出た時の対処
 (1-1) エラーメッセージ
 (1-2) 原因
 (1-3) 対処

(1) C++で「静的でないメンバー参照は特定のオブジェクトを基準とする相対参照である必要があります」エラーが出た時の対処

(1-1) エラーメッセージ

(エラーメッセージ)
E0245 静的でないメンバー参照は特定のオブジェクトを基準とする相対参照である必要があります
 
(図111)
 

(1-2) 原因

「staticでない」メソッドを「クラス名::関数名()」のような形で呼び出すとこのエラーになります。

●staticとは?

変数や関数が「static」キーワード付きで定義されている場合、プログラムの実行中はメモリがずっと割り当てられ、それをずっと持ち回ります。なので、変数や関数が複数回呼ばれる場合等に値を引き継いで更新していくような場面で便利です。加えて、文法的な特徴としては初期化せずとも使用出来る点が挙げられます。
 
簡単な例を見てみたいと思います。まずはstaticでないメソッドです(通常のメソッド)。
 

●staticでないメソッド

以下のFruitクラスでは「calcPrice」は普通のvoid型のメソッドとして定義されています。

//# 親クラス
class Fruit {

  //# 親クラス内のメソッド
  public:
    //# ▲修正前
    void calcPrice(int amount) {
      cout << "フルーツの値段:" << amount * 100 << endl;
    }
};
 
これを次のように呼び出そうとすると、Fruitクラスのオブジェクトを作っていないため、エラーになります。
 
Fruit::calcPrice(5);
 
なので、staticでないメソッドを呼び出す場合は、次のようにオブジェクトを生成してメソッドを呼びます。
 
//# オブジェクトを生成
Fruit fr;
//# メソッドを呼び出し
fr.calcPrice(5);
 
次にstaticで宣言したメソッドを見てみます。

●staticなメソッド

以下のFruitクラスでは「calcPrice」はstaticなメソッドとして定義されています。
 
//# 親クラス
class Fruit {

  //# 親クラス内のメソッド
  public:
    //# ●修正後
    static void calcPrice(int amount) {
      cout << "フルーツの値段:" << amount * 100 << endl;
    }
};
 
staticなので、オブジェクトを作らずに次のように呼び出せます。「::」はスコープ解決演算子と呼ばれ、メソッドが所属するクラスを明示的に表現しています。
 
Fruit::calcPrice(5);
 

(1-3) 対処

以上を踏まえると、呼び出すメソッドに「static」を付ける事によって、エラーが解消すると思います。
 
まずは修正前のプログラムです。「▲修正前」が修正箇所ですが、staticが付いていないのでエラーになります。
(修正前)
#include <iostream>
#include <string>
using namespace std;

//# 親クラス
class Fruit {

	//# 親クラス内のメソッド
	public:
		//# ▲修正前
		void calcPrice(int amount) {
			cout << "フルーツの値段:" << amount * 100 << endl;
		}
};

//# 親クラスを継承したクラス
class Apple : public Fruit {

	//# 親クラスを継承したクラス内のメソッド
	public:
		//# ▲修正前
		void calcPrice(int amount) {
			cout << "リンゴの値段:" << amount * 200 << endl;
		}
};

int main() {

	Fruit::calcPrice(5);
	Apple::calcPrice(5);
	return 0;
}
 
修正後のプログラムです。「●修正後」の下の部分で、メソッドをstaticにしているのでエラーが解消しています⇒(図131)
 
(修正後)
#include 
#include 
using namespace std;

//# 親クラス
class Fruit {

	//# 親クラス内のメソッド
	public:
		//# ●修正後
		static void calcPrice(int amount) {
			cout << "フルーツの値段:" << amount * 100 << endl;
		}
};

//# 親クラスを継承したクラス
class Apple : public Fruit {

	//# 親クラスを継承したクラス内のメソッド
	public:
	  //# ●修正後
    static void calcPrice(int amount) {
      cout << "リンゴの値段:" << amount * 200 << endl;
    }
};

int main() {

  Fruit::calcPrice(5);
  Apple::calcPrice(5);
  return 0;
}
 
(図131)
 

Adsense審査用広告コード


Adsense審査用広告コード


-C++

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

C++の「int **g = new int*;」の意味について

  <目次> (1) C++の「int **g = new int*;」の意味について  (1-1) 「int **g = new int*;」の意味  (1-2) サンプルで理解を深める …

C++の値渡しと参照渡しの使い分けや違いについて

<目次> (1) C++の値渡しと参照渡しの使い分けや違いについて  (1-1) 「値渡し」とは?  (1-2) 「参照渡し」とは?  (1-3) 「値渡し」と「参照渡し」の使い分け (1) C++の …

パイプ通信とは?概要やサンプルプログラムをご紹介

  <目次> (1) パイプ通信とは?概要やサンプルプログラムをご紹介  (1-1) パイプ通信の概要  (1-2) パイプ通信の構文  (1-3) パイプ通信のサンプルプログラム①(単一プ …

Valgrindとは?使い方や概要をご紹介(メモリリーク検知ツール)

  <目次> (1) Valgrindとは?使い方や概要をご紹介(メモリリーク検知ツール)  (1-1) Valgrindとは?  (1-2) Valgrindの導入方法  (1-3) Va …

CORBA通信のPOA(Portable Object Adapter)とは?

  <目次> (1) CORBA通信のPOA(Portable Object Adapter)とは?  (1-1) 概要と特徴  (1-2) 一般的なPOAの処理構成  (1-3) POAの …

  • English (United States)
  • 日本語
Top