UNIXのC++で共通クラスを作ってみんなで使いたい

このQ&Aのポイント
  • UNIXのC++で共通クラスを作成し、みんなで使えるような形にする手順を教えてください。
  • クラスの定義部分を別ファイルにしてヘッダーファイルにするべきかどうか、共通クラスをどのような形で提供するべきかが分からない
  • 他の人のプログラムで共通クラスを使用するための手順が分からない
回答を見る
  • ベストアンサー

UNIXのC++で共通クラスを作ってみんなで使いたい。

Linux上で稼動するあるC++のプログラムを作るのに、 みんなで使えるような、共通クラスを作りたいと思っています。 クラス自体の作り方(プログラムコード)はだいたい分かるのですが、 それをどのような形(lib?またはアーカイブ?またはdll?)で 配布すると、みんなが使いやすいものになるのかが分かりません。 手順など、どなたか教えてください。 私が何とか予想できる手順を以下に書きます。 (1)普通にクラスを作成する。(例えばaaa.cppと言う名前のファイルに)   public class AAA{ public: void init(); void clean(); private: int elems; } void AAA::init(){ elems = 0; } void AAA::clean(){ elems = 0; } ※この時点でクラスの定義部分だけをヘッダーファイルとして   別ファイルにしておいた方が良いのでしょうか? (2)このクラスをコンパイルして、みんなに提供できる何らかの形にする。  ※ここがよく分かりません!!  ※”.a”というアーカイブを作成する方法は知っています。   これを作れば良いのでしょうか? (3)出来上がった共通クラスをどうにかして、他の人のプログラムで使えるようにする。  ※予想としては、(1)で作ったクラス定義のヘッダーファイルを   includeする(のかな?)   それから、コンパイルする時にmakefileの中で(2)で作った   ライブラリ(?)を一緒にリンクする(のかな?)  ※プログラム中では、いきなり    AAA testBuf = new AAA(); testBuf.init(); などと使えるのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.1

> 私が何とか予想できる手順を以下に書きます。 やってみれば、すぐ分かることなのに。というのも、orange_pie さんが考えて いる通りで、実現できるから、です。 他のプログラム(コンパイル単位)で必要なのは、クラスの宣言です。なので、 class AAA{ public: void init(); void clean(); private: int elems; }; は、ヘッダファイル aaa.h に記述します。クラスのメソッドの定義は、aaa.cpp に 記述します。 #include "aaa.h" void AAA::init() { elems = 0; } void AAA::clean() { elems = 0; } で、その定義をコンパイルしてアーカイブに入れておきます。(知っているようですが)例えば、 % gcc -c aaa.cpp % ar -r libaaa.a aaa.o 使う側では、ヘッダファイルをインクルードするだけで、コンパイルが通ります。 #include "aaa.h" int main() { AAA *testBuf = new AAA(); testBuf->init(); return 0; } リンクする際には、先程作成したアーカイブが必要になります。 % gcc -o test_aaa test_aaa.cpp -laaa ね、質問に書いてあるままでしょう? # 細かい記述ミスなんかは訂正をしています

orange_pie
質問者

お礼

すてき、すてき!!(^○^) 分かりやすくて素敵!! ありがとうございます。早速やってみます。 <他のプログラム(コンパイル単位)で必要なのは、クラスの宣言です。>とか <ヘッダファイル aaa.h に記述します。>とか <クラスのメソッドの定義は、aaa.cpp に記述します。 >とか、 <使う側では、ヘッダファイルをインクルードするだけで、コンパイルが通ります。 >とか、 知りたい事の全てが、これらの言葉ですんなり理解できました。 「痒いところに手が届いちゃった」という感じです。 こんな長ったらしくて要点がまとめられない質問から 知りたい事を分かってもらえたのがとっても嬉しいです。 ありがとうございます。

その他の回答 (1)

  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.2

> 知りたい事の全てが、これらの言葉ですんなり理解できました。 解答をした甲斐があった、というもんです :-) 蛇足かもしれませんが、先の回答は、あくまでも、最初の取っ掛かり部分でしかないということを 言っておきます。 共通のクラスが増えてゆくことで、 ・あるクラスが別のクラスと関連を持っている ・Cインターフェースの関数 ・インライン関数 ・テンプレートクラス なんてことがでてくるので。 まあ、そのときには、また質問をしてみればいいんですけどね。 とりあえず、さっきの回答をひとつだけ補足しておきます。 インクルードファイルの二重読み込みの防止だけはしておいた方が良いでしょう。 インクルードファイルの内容を以下のような感じのマクロで括っておきます。 #ifndef AAA_DEFINED #define AAA_DEFINED class AAA { public: void init(); void clean(); private: int elems; }; #endif /* AAA_DEFINED */ /usr/include 配下のヘッダファイルなんかを見てみると、だいたいこんな感じ になっているのが分かると思います。

orange_pie
質問者

お礼

そうですね。 >共通のクラスが増えてゆくことで、 >・あるクラスが別のクラスと関連を持っている >・Cインターフェースの関数 >・インライン関数 >・テンプレートクラス >なんてことがでてくるので。 ム(-"-;)むむむ。。。。 >まあ、そのときには、また質問をしてみればいいんですけどね。 そうします。今は難しいことは後回しにして、基本的な使い方だけ 会得することにします。 >インクルードファイルの二重読み込みの防止だけはしておいた方が良いでしょう。 そうですね。いつもはやっていますが、今はまだヘッダーファイルを配布した時の事まで考えていませんでした。そうします。 ありがとうございました。

関連するQ&A

  • C++のdllの作り方を教えてください。

    こんにちは。 先週、「UNIXのC++で共通クラスを作りたい。」って言う質問をした orange_pieと申します。 そのバージョンアップ質問として、作成した共通クラスをDLLにして みんなに提供したいのですが、コンパイルはアーカイブを作る時と どう違うのでしょうか? ちなみに、コンパイルした後でarコマンドを使ってアーカイブを作っていました。 % gcc -c aaa.cpp % ar -r libaaa.a aaa.o dllを作るには、ヘッダーファイルの記述に何か特別なものが必要ですか? また、できあがったdllを使う側では、ヘッダーファイルをインクルードして LIBパスの通ったところにdllを入れておけば良いのでしょうか? どなたか教えてください。

  • C#でクラス継承について

    下記のようなコードは、可能なのでしょうか? // クラス定義 abstract class Base { int a; Public int A { get{ return a; } } } class Sub1 : Base { int b; public int B { set { b = value; } } }; class Sub2 : Base { // 中略 } static class Program { [STAThread] static void Main(string [] args) { Base aaa = new Sub1(); Base bbb = new Sub2(); func(aaa); // ここでCS1502, CS1503 func(bbb); // ここでCS1502, CS1503 } void func(Sub1 _aaa) { // 中略 } void func(Sub2 _bbb) { // 中略 } } コメントに書いたとおり、CS1502(引数が合わない)が出ます。 func((Sub1)aaa); の様にキャストしないと、動作させることは難しいでしょうか? ※ 実際のコードでは、func(aaa), func(bbb)の呼び出し部分をループでまわしたいと考えています。

  • 現在のクラスを生成したクラスに渡したい

    親クラスで生成した子クラス(ダイアログ)から親クラス(ダイアログ)の関数などを使えるようにしたいと思っております。 ちなみに継承クラスで親クラスの関数を使うのではなく、親クラスそのもの(ダイアログ表示)を子クラスから変更できるようにしたいです。 (簡単になりますが…)プログラムの構成は以下のようになっており、thisポインタを渡すか所でエラーが起こってしまいます。 ------------------------------------------------ class AAA { BBB *b; void classBBB{ b = new BBB(this); // こういうことがしたいが、できない void fun( int a ); // ダイアログの表示が変更する(予定) }; class BBB { AAA *a; BBB(AAA *pDlg){ a==pDlg; } void fun(){ int b; a->fun(b); } // 親クラスの関数を呼び出したい }; ------------------------------------------------ ただし、class Aとclass Bを生成する上位階層のプログラム構築をすることはなしとします。 ------------------------------------------------ こんな感じ AAA *a = new AAA(); BBB *b = new BBB(a); ------------------------------------------------ どうしてもclass AAAからclass BBB呼び出したいと思ってます。 何か良い解決法があれば、教えていただきたいです。 宜しくお願い致します。

  • クラスのメンバ関数を別ファイルで定義したときのバグ

    C++ においてヘッダファイルで宣言したクラスのメンバ関数を別のソースファイルで定義して、コンパイルするとうまくいきません。エラーは出ないのですが、同名の何もしない関数としてコンパイルされているようなのです。クラスのメンバ関数を宣言したのと同じヘッダに書くとちゃんとコンパイルされます。 どうしてそうなるのか、いまいち原因がわかりません。

  • 共通クラス作成について

    VisualStudio.NET2003 C# で開発をしている、超初心者です。 共通クラスを作成することになり、どのようにコーディングしてよいのか途方にくれております。StreamIOなどを使用すればよいところまではわかったのですが、共通クラスを作成したことがなく、どのように書けばよいのか全くイメージがわきません。処理としては、ファイル作成(ファイル名は日付)、書き込み(ヘッダ部分(固定)とSQLデータ一覧)から、ファイルクローズです。特に書き込みの部分でSQLデータをメゾットにどのように渡したらよいのかわかりません。 皆様、お忙しいところ申し訳ありませんが、なにとぞご教授よろしくお願いいたします。

  • 定義されているのにエラーになる

    閲覧ありがとうございます。 C言語のプログラムの話です。 ソースファイルaaa.cでstdio.hをincludeしています。 stdio.hには extern FILE _iob[_NIOBRW]; というのが定義されているにも関わらず、 コンパイルすると、 aaa.o:aaa.c:(.data+0x58): undefined reference to '_iob' というエラーが出ます。 aaa.cでは_iobに関する宣言はしていませんが、それを使うこともしていません。 ヘッダファイルでexternで宣言してるからかなと思い、ソースファイルにexternなしの宣言を書き足したら、コンパイルは通りました。 今回は元々既にあるプロジェクトの改修だったのですが、宣言を消したりしていません。 しかし、その部分は元々ヘッダファイルに宣言などしなくてもコンパイルが通ってました。 昔はヘッダファイルでexternで宣言してたらソースファイルではしなくてオッケーみたいな感じだったんですかね? 私自身、あまりよく分かってなくて文章もめちゃくちゃですみません。 不足している情報があればできる範囲でお伝えしますので、ご協力よろしくお願いいたします。

  • c++,ある関数のクラスから別のクラスの関数を呼ぶ

    c++で、あるクラスのメンバ関数から、別のクラスのメンバ関すを呼びたいのですが、どのようにしたらできますか? 例えば、以下のような単純なコードを考えています。やりたいことは、Aのメンバ関数であるaaa()からBのクラスであるbbb()を呼びたいと思っています。その理由を少し説明します。ここでは、Aというクラスとmain関数はオープンソースコードを例えています。できるだけ、元のオープンソースコードを書き換えずに新たな機能を拡張したいと思っています。そこで、Bというクラスを使って、元のオープンソースコードに機能を拡張しようとしています。このような理由なので、bbb()という関数はaaa()という関数から呼びたいです。メイン関数には何も書き加えないのがベストです。 現状では、実行すると「this is aaa」という出力しか出ません。ここに「this is bbb」の出力を加えたいです。クラスAとBにある程度コマンドを追加して、解決できないでしょうか。 #include <iostream> using namespace std; //------------------------------------------------------ class A{ public: void aaa(); virtual void bbb(){} }; //------------------------------------------------------ //------------------------------------------------------ class B : public A{ public: void bbb(); }; //------------------------------------------------------ //------------------------------------------------------ void A::aaa() { cout << "this is aaa \n"; bbb(); } //------------------------------------------------------ //------------------------------------------------------ void B::bbb() { cout << "this is bbb \n"; } //------------------------------------------------------ //------------------------------------------------------ int main() { A a; a.aaa(); return 0; } //------------------------------------------------------

  • HEW3とBorlandC++でクラス定義の違い???

    いつもお世話になってます! 超初心者です。 よろしくお願いしますm(__)m C++のヘッダファイルに、クラスの定義をしました。 mainプログラム内でそのクラスのオブジェクトを定義しました。 BorlandC++では、そのプログラムは問題なくコンパイル&実行できるのですが、 HEW3ですと、「語句の並びが文法にあっていません」という旨のエラーが出ます。 クラス定義も、一般の書籍に書いてあるとおりに定義しているし、BorlandC++ではエラーになりません。 HEWだと定義の仕方が特殊なのでしょうか?? 私の知識レベルではHEWのマニュアルが難しくてなかなか理解できません。 どうか初心者にもわかりやすく解説していただけませんでしょうか? よろしくお願いいたしますm(__)m

  • 複数ファイルによる共通の外部変数定義について

    初歩的な質問なのですが、今各関数をファイルごとに分けて記述しようとしています。 ここで詰まっているのでできればご教授お願いします ファイル構成は プログラムファイル main.cpp sub.cpp ヘッダーファイル  myheader.h(main.cppとsub.cpp両方でインクルード) ヘッダーファイルには両方のプログラムファイルで使う変数が定義してあります。 それでmain.cppとsub.cpp両方で同じ変数を使いたいのですがコンパイルエラーが発生してしまいます。 内容はsub.obj側で「i(共通のループカウンタ)はmain.objですでに定義されています」というものです。 とにかく私のやりたいことはヘッダーに外部変数を定義して両方のプログラムファイルで使いたいというものです。 もしかしたらファイルを分けるにも何か設定が必要なのでしょうか? 私はただ[プロジェクト]→[プロジェクトに追加]→[新規作成]でソースファイルを作っているだけなんですが・・・ 上記の状態を回避する方法はあるのでしょうか?

  • C++ クラスの作り方

    Windows10の上で、Visual Studio Community2015 を使ってC++を勉強中の者です。 Time クラスというのを定義して使おうとしましたが、クライアント側のプログラム作成中にエラーメッセージが出てきて、色々考えましたがどこが悪いのかわかりません。 プログラム自体は時刻を設定してそれを表示させるだけのものです。 詳しい方がいらっしゃいましたら、ご教授お願い致します。 問題のエラーメッセージ; "consoleApplication69.cpp" を作成中にエディターの中で、波型の赤線が出ているところにカーソルを持っていくと、次の3か所でそれぞれ次のようなエラーメッセージが出てきます。 (1) #include "time3.h" のところ: 「ソースファイルをひらけません。"time3.h"」 (2) 関数 incrementMinute( )のプロトタイプのところ:「不完全な型は使用できません。」 (3) 最初のパラメーター Time & のところ:「識別子 Time が定義されていません。」 以下に、 1: 私が作ったTimeクラスの定義のあるヘッダー "time3.h", 2: メンバー関数の定義ファイル "time3.cpp" 3:クライアント側プログラム "consoleApplication69.cpp" の3つのソースコードをコピーします。 "time3.cpp" については長いので、上の半分だけにしました。 ****************************************************** 1: "time3.h" ******************************************************** #pragma once // header file for Time class // time3.h #ifndef TIME3_H #define TIME3_H class Time { public: Time(int = 0, int = 0, int = 0); ~Time(); void setTime(int, int, int); void setHour(int); void setMinute(int); void setSecond(int); int getHour(); int getMinute(); int getSecond(); void printUniversal(); void printStandard(); private: int hour; int minute; int second; }; #endif *********************************************** 2: "time3.cpp" ************************************************ #include <iostream> #include <iomanip> #include <cstdlib> #include <ctime> #include <cmath> #include <cstring> #include "time3.h" using namespace System; using namespace std; Time::Time(int hr, int min, int sec) { setTime(hr, min, sec); } void Time::setTime(int hr, int min, int sec) { setHour(hr); setMinute(min); setSecond(sec); } void Time::setHour(int hr) { hour = (0 <= hr && hr <= 23) ? hr : 0; } void Time::setMinute(int min) { minute = (0 <= min && min <= 59) ? min : 0; } void Time::setSecond(int sec) { second = (0 <= sec && sec <= 59) ? sec : 0; } ********************************************************* 3: "consoleApplication69.cpp" ********************************************************* // ConsoleApplication69.cpp : メイン プロジェクト ファイルです。 #include "stdafx.h" #include <iostream> #include <iomanip> #include "time3.h" using namespace System; using namespace std; //prototype void incrementMinute(Time &, const int); int main() { Time t; t.setHour(2); t.setMinute(10); t.setSecond(30); cout << " current time is "; cout << setfill('0'); cout << setw(2) << t.getHour() << ":"; cout << setw(2) << t.getMinute() << ":"; cout << setw(2) << t.getSecond() << "\n"; return 0; } // function void incrementMinute(Time &tt, const int num) { // まだ未定義 } またソリューションエクスプローラーの画面写真も添付します。 ヘッダーファイルもインクルードしていますし、ソリューションの中に入れたつもりですが、なぜ Time が定義されていないといわれるのでしょうか? どうぞよろしくお願いいたします。