質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.11%

自作ヘッダファイルがインクルードできない

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 133

toyo_69

score 13

プログラミング初学者です。

自前のPC(Mac)で主にAtomエディタを用いて、プログラムをmain関数部、クラスの宣言をするヘッダファイル部、メンバ関数の内容の記述部に分けて書いているのですが、main関数で使うクラスのヘッダファイルをインクルードする際や継承先のクラスを宣言しているヘッダファイルで継承元のクラスのヘッダファイルをインクルードしようとすると毎回エラーとなってしまいます。そこでヘッダファイルの代わりにメンバ関数の内容の記述部をインクルードすると上手く動作するのでそれでやり過ごしています。本来なら自作ヘッダファイルのインクルードが通り問題なくプログラムが実行できるはずですがそれだと上手くいかないです。Atomの記事が少なく、自分では解決できそうにないです。どなたかご教授願います。

インストールしてあるコミュニティーパッケージは
・busy-signal(2.0.1)
・expose(0.15.0)
・cpp-compiler(3.0.7)
・intentions(1.1.5)
・japanese-menu(1.15.0)
・linter(2.3.1)
・linter-gcc(0.9.0)
・linter-ui-default(1.8.1)
・memory-bro(2.1.0)
・script(3.26.0)
・script-runner(2.5.0)
です。

このような分割プログラムにすると毎回どれも自作ヘッダファイルがインクルードできない状態なのでプログラム面には問題ないかと思われますが念のため問題が発生するソースコードの例を下記に置いておきます。
コンストラクタを用いてデフォルト引数を指定し、名前、課題の点数、平均点、合計点数を表示させるプログラムです。

/*main.cpp*/
#include "Student.cpp"
#include "StudentEx.cpp"

int main()
{
    //オブジェクトを初期化
    Student taro("taro", 100, 80);
    taro.CalcAve();
    cout << taro.Name() << endl;
    cout << "kadai1:" << taro.GetKadai1()
        << " kadai2:" << taro.GetKadai2() << endl;
    cout << "ave:" << taro.Average()
        << " sum:" << taro.GetSum() << endl;

    //オブジェクトを初期化
    StudentEx jiro("jiro", 90, 70, 50);
    jiro.CalcAve();
    cout << jiro.Name() << endl;
    cout << "kadai1:" << jiro.GetKadai1()
        << " kadai2:" << jiro.GetKadai2()
        << " kadai3:" << jiro.GetKadai3() << endl;
    cout << "ave:" << jiro.Average()
        << " sum:" << jiro.GetSum() << endl;

    return 0;
}
/*Student.h*/
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <iostream>
using namespace std;
#pragma once

class Student {
public:
    char name[20];  //氏名
    int kadai1;  //課題1の点数
    int kadai2;  //課題2の点数
    int ave;   //平均点

    void SetName(const char *n) { strcpy(name, n); }
    void SetKadai1(int k1) { kadai1 = k1; }
    void SetKadai2(int k2) { kadai2 = k2; }

    char *Name() { return name; }
    int GetKadai1() { return kadai1; }
    int GetKadai2() { return kadai2; }
    int Average(){ return ave; }

    int GetSum();   //合計点を求める
    void CalcAve(); //平均点を求める
    //コンストラクタ
    Student() {    cout << "Studentのコンストラクタ" << endl; }
    //引数付きコンストラクタ
    Student(const char *name, int k1, int k2);
};
/*StudentEx.h*/
#include "Student.h"
//StudentExの二重定義を防止
#pragma once

class StudentEx : public Student {
public:
    int kadai3;
    void SetKadai3(int k3) { kadai3 = k3; }
    int GetKadai3() { return kadai3; }
    int GetSum();
    void CalcAve();
    //コンストラクタ
    StudentEx() { cout << "StudentExのコンストラクタ" << endl; }
    //引数付きコンストラクタ
    StudentEx(const char *name, int k1, int k2, int k3);
};
/*Student.cpp*/
#include "Student.h"

Student::Student(const char *name, int k1, int k2) {
    SetName(name);
    SetKadai1(k1);
    SetKadai2(k2);
}

int Student::GetSum()
{
    return kadai1 + kadai2;
}

void Student::CalcAve()
{
  ave = (kadai1 + kadai2) / 2;
}
/*StudentEx.cpp*/
#include "StudentEx.h"
//基底クラスのイニシャライザを指定
StudentEx::StudentEx(const char *name, int k1, int k2, int k3) : Student(name, k1, k2) {
    SetKadai3(k3);
}

int StudentEx::GetSum() {
    int sum;
    //基底クラスのGetSum()を呼び出して機能を追加
    sum = Student::GetSum();
    sum += kadai3;
    return sum;
}

void StudentEx::CalcAve() {
    //基底クラスのCalcAve()を呼び出して機能を追加
    Student::CalcAve();
    ave = (2 * ave + kadai3) / 3;
}

こういったプログラムで例えば上記の例ではmain部の始めの行でStudentとStudentExの関数内容記述部をインクルードしていますが、代わりにそれぞれのヘッダファイルをインクルードすると次のようなエラーが出力されます。Xcodeではヘッダファイルをインクルードして実行できたのでAtom側の何かしらの問題かと思われます。

Undefined symbols for architecture x86_64:
  "Student::GetSum()", referenced from:
      _main in main-b2a933.o
  "Student::CalcAve()", referenced from:
      _main in main-b2a933.o
  "Student::Student(char const*, int, int)", referenced from:
      _main in main-b2a933.o
  "StudentEx::GetSum()", referenced from:
      _main in main-b2a933.o
  "StudentEx::CalcAve()", referenced from:
      _main in main-b2a933.o
  "StudentEx::StudentEx(char const*, int, int, int)", referenced from:
      _main in main-b2a933.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • cateye

    2020/06/30 23:29 編集

    問題の有るソースを提示して下さい。

    キャンセル

  • cateye

    2020/07/01 14:49 編集

    _CRT_SECURE_NO_WARNINGSって、Windows?・・・これ、VS用です^^;
    で、リンクエラーですが?・・・Atomって使ったことがないのですが、プロジェクトって作れないのですか?
    Student.cppやStudentEx.cppの関数が見つからないと言っています、一緒にコンパイルしてるんですよね?
    #・・・macはCotEditorばっかv^^・・・IDEは、Geany・・・

    キャンセル

回答 1

0

・インクルードファイルの記述方法は合っていますか?
・・・#include "〜"

・別ディレクトリに有るファイルをインクルードする時は、コンパイルオプションに該当ディレクトリを指定しましょう。
・・・-I

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/01 00:06

    エラーは、エラーメッセージを、そのまま(加工せずに)貼り付けて下さい。

    キャンセル

  • 2020/07/01 13:54

    ソースコードを追加しました。インクルードファイルの記述方法は合ってると思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.11%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる