• ベストアンサー

コンストラクタについて

プログラム初心者です classを使うときに使うコンストラクタについて教えてください なぜ自動で実行できるのか不思議です 質問1 このコンストラクタの使い道を教えてください。 質問2 PHPはC言語で作られているのですよね?コンストラクタを自動で実行しているC言語の処理はどうなっているのですか? 質問3 classと関数の違いがわかりません。ネットで調べると「classだと変数を保持できる」とでますが関数だと保持できないのでしょうか? よろしくお願いします

  • flash0
  • お礼率97% (297/306)
  • PHP
  • 回答数2
  • ありがとう数4

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

  • ベストアンサー
noname#244856
noname#244856
回答No.1

クラス・オブジェクトの概念について先に学んでください。 http://www.shigeweb.jp/php/project_p/?page=class§ion=first 回答1 オブジェクトを作るときに「必ず」実行しなければいけない処理がある場合、それはコンストラクタに書いたり、コンストラクタから呼び出したりします。 回答2 「それはそういうもの」として深入りしない方がいいように思います。C言語レベルでの記述を知ろうとすることはいいと思いますが、それ以前に「なぜ自動で実行できるのか不思議です」という疑問の本質が分かりません。それを言い出すと「PHPの型の自動変換ってC言語レベルでどう書いてるの?」「json_decode関数で一発でデコードできるけどどうなってるの?」などの疑問も無限に沸いてくることでしょう。 回答3 関数でも変数を保持することは出来ます。 「静的変数」 http://www.php.net/manual/ja/language.variables.scope.php#language.variables.scope.static しかし、これで出来ることには限度があります。 複数の関数(メソッド)間で1つの変数を共有しつつ保持したい場合、それはオブジェクトにしか出来ません。 私は実装例として静的変数を http://qiita.com/mpyw/items/c39b9ee695a5c2e74627 で利用していますが、正直1つの関数にまとめるにはこれぐらいの処理が限界だと思います。もっと処理を増やせばかなり見にくくなり、クラス化することが不可欠になるでしょう。

flash0
質問者

お礼

回答ありがとうございます 質問1と2は納得しました 質問3なのですがピンときません >複数の関数(メソッド)間で1つの変数を共有しつつ保持 これがどうゆものかわかりません 10行くらいのコードで2つの違いを教えていただけると助かります 学習用の意味のないコードで結構です 関数でもグローバル変数を使えば同じことできるような気がして頭こんがらがっています

その他の回答 (1)

noname#244856
noname#244856
回答No.2

短いコードしか書いていない場合は、グローバル変数のデメリットになかなか気づかないかもしれません。 大きな規模のアプリを作る場合はグローバル変数なんか使ってたら弊害がありすぎてコーディングに苦労すると思います。 例えば、(普通はオートロードに任せてこんなことしませんが) require_once('A.php'); require_once('B.php'); require_once('C.php'); として呼んでいるとして、A,B,Cともそれぞれ中でグローバル変数をバリバリ使っているとします。 「あれ・・・B.phpの中で$idって変数使ってたけどこれってA.phpの中にもあったっけ・・・影響ないのかな・・・」 とか思ったりしませんか?このように変数名が競合したりする問題を引き起こすのがグローバル変数です。PHP5.3から利用可能な「名前空間」を使えばこの問題は解消することが出来ますが、名前空間に甘んじてグローバル変数を多用するならば本末転倒です。

flash0
質問者

お礼

理解できました ありがとうございました

関連するQ&A

  • コンストラクタ・デストラクタ

    プログラミング言語はC++ C++を触り始めたばかりの素人です。 コンストラクタとデストラクタについて質問です。 下記に参考にしているウェブページから簡潔にしてコードを書いてみました。 コンストラクタ、デストラクタの中はそれぞれに、○○が呼び出されましたと書いてあるだけでよく分からなかったので別のウェブページを見たら コンストラクタは Sample::Sample(){ n=0; } みたいな例があったのですが、このように変数に予め何かの値を代入しておくという事で合ってますか? デストラクタは理解できていません。 下記の例では、どのような処理を書けばいいのでしょうか? #include<iostream> using namespace std; class Sample { private: int n; public: void Show(); Sample(); ~Sample(); }; void Sample::Show() { cout << n << endl; } Sample::Sample() { // n=0; std::cout << "コンストラクタが呼び出されました" << std::endl; } Sample::~Sample() { // どんな処理? std::cout << "デストラクタが呼び出されました" << endl; } main() { Sample sample; sample.Show(); return 0; } 実行結果 コンストラクタが呼び出されました 1     ←コンストラクタ関数内の//を削除で0になることは確認 デストラクタが呼び出されました

  • コマンドを実行してコマンドライン文字列を読み込む

    C言語(他の言語でも)で、コマンドを実行して結果の文字列を取得できるような関数はないでしょうか? コマンドを実行したプログラム内の変数に文字列として保持して、処理したいと考えています。 Windowsです。 よろしくお願い致します。

  • コンストラクタの使い方?

    僕はまだJavaを勉強し始めて1ヶ月ぐらいの初心者なんですけども、現段階では基本的な文法を勉強し終えた(かなと思っている)ので、Swingのほうに早速とりかかりました。その際にすごく疑問に思ったことがあるので、皆さんにお尋ねします。 public class A ......main..... class B extends Frame{   public B(String stitle){    super(stitle);  } } super(stitle)のところでFrameクラスのコンストラクタが呼び出されていますよね。そこでFrameクラスのコンストラクタの定義を見てみると、僕が今まで学んできたような定義がなされていないんですけども。僕が今まで学んできたものというのは、 class Car {   private int num;   private double gas;   public Car()   {    System.out.println(車を作成しました。)   } } class C { ....main...   {    Car car1=new Car();   } } この場合の実行結果というのは、 「車を作成しました。」という文章が表示されはづですけど、これって言うのはSystem.out.println(車を作成しました。)のようにきちんと定義しているからですよね。それに対してFrameクラスのコンストラクタの定義には説明はあるものの、実行処理するための定義がされていないような気がするんですけども・・・。まだ僕はオブジェクト指向というものを理解できていないから、このようなわけのわからない質問をしている(と思う)のですが、よろしければどなたか分かりやすく教えてください。

    • ベストアンサー
    • Java
  • Javaのコンストラクタについて教えてください

    Javaを勉強している初心者です。 次のようなプログラムがあります。 このプログラムでclass aおよびclass bのデフォルトコンストラクタ a() {}とb() {}をコーディングしていないとコンパイルエラーになります。 b() {}についてはclass bのパラメータのあるコンストラクタb(String s)がサブクラスclass cから明示的に呼ばれていないのでデフォルトコンストラクタb() {}をコーディングしないとエラーになる…と考えればよいのでしょうか。 それでは、a() {}はなぜ必要なのでしょうか。 どなたか教えてください。 class a { a() {} a(String s) { System.out.println("In a's constructor..."); System.out.println(s); } } class b extends a { b() {} b(String s) { super(s); System.out.println("In b's constructor..."); System.out.println(s); } } class c extends b { c(String s) { System.out.println("In c's constructor..."); System.out.println(s); } public void some() { System.out.println("something..."); } } public class appJ01 { public static void main(String args[]) { c obj = new c("Hello from Java!"); } } 

  • PHP5 コンストラクタや初期化の意味がわからない

    プログラミング初心者です。本を参考にしてPHPを勉強しています。 クラスの章でコンストラクタについて以下のように書かれていました。 コンストラクタはインスタンス化のタイミングで実行されるという性質上、 プロパティ(メンバ変数)やクラスで使用する各種リソースの初期化 といった処理を記述するのが一般的です。 初期化処理が不要な場合、コンストラクタは省略可能。 ここで質問です。 インスタンス化を行うのは初期化するためということでしょうか? 「~といった処理を記述するのが一般的」ということは、初期化が 本来の目的ではないという意味にもとれますがどうなんでしょうか。 また静的メソッドについては、 「インスタンス化を行わなくても利用できるメソッド」 と書かれていましたが、何がどう違うのか分かりません。 初期化とは何でしょうか?またなぜ初期化を行うのでしょうか? 静的メソッドと何が違うのでしょうか?

    • ベストアンサー
    • PHP
  • 【PHP】コンストラクタ―について

    コンストラクタ―について検索して調べると概ね以下のように説明されています。 ---------------------------------- コンストラクタ インスタンス生成時にオブジェクトを初期化したい場合にコンストラクタメソッドを使用できます。 コンストラクタメソッドは以下のように引数を指定する事もでき、インスタンス生成時に__construct()が自動的に実行されます。 ---------------------------------- イマイチ判然としません。 「newによってインスタンスを作成される時に自動的に呼び出されるもの」と自分では解釈していました。 例えば以下のような場合 public function __construct($text) { $this->text = $text; } 【$text】の値をnewされることによって自動的に「保持」されるということなのでしょうか? 実際に表示させるときは【$posts[0]->show();】(show()メソッド)で表示させるわけですよね? その上には【private $text;】でプロパティがあります。 ごく基本的な質問かと思いますが、【public function __construct($text)】 コンストラクタ―を作成する理由がよくわかりません。 初学者でも分かりやすいように解説していただけないでしょうか? 宜しくお願い致します。 <記述サンプル> ------------------------------- <?php class Post { private $text; public function __construct($text) { $this->text = $text; } public function show() { printf('%s' . PHP_EOL, $this->text); } } class SponsoredPost extends Post { private $sponsor; public function __construct($text, $sponsor) { parent::__construct($text); $this->sponsor = $sponsor; } public function showSponsor() { printf('%s', $this->sponsor); } } $posts = []; $posts[0] = new Post('hello'); $posts[1] = new Post('hello again'); $posts[2] = new SponsoredPost('hello hello', 'Yahoo'); $posts[0]->show(); $posts[1]->show(); $posts[2]->show(); $posts[2]->showSponsor();

    • ベストアンサー
    • PHP
  • コンストラクタとデリゲートの意味を教えてください。

    コンストラクタは、起動時に自動生成される処理のことをいいますか? 1度だけ実行されるクラスをコンストラクタと言っているのですか??? デリゲートは、クラスからメソッドを呼び出すことをデリゲートといいますか? クラスから処理を別に渡すとそれはデリゲートですか???

  • djUnit コンストラクタがprivateでテストが行えない

    djUnit コンストラクタがprivateでテストが行えない djUnitを使っております。 テスト対象のメソッドにアクセスしてテストを行いたいのですが、 どうもそれができません。 理由としては、コンストラクタがprivateになっているから?です。 (「コンストラクター TestManager() は不可視です」というエラーが出ます。) コンストラクタのprivateを消せば、テスト対象のメソッドにアクセスできるのですが、 実際には消してテストをしてはだめということになっています。 コンストラクタがprivateでもdjUnitでテストが行える方法がございましたら、 書き方をご教授いただけないでしょうか? どうかよろしくお願いいたします。 一応下記が詳細です。 (クラス名、コンストラクタ名、メソッド名) ------------------------ [クラス] public final class TestManager [コンストラクタ] private TestManager() { } [テスト対象のメソッド] public Structure testCreate(byte[], byte[], byte[]) ----------------------- 色々試したのですが、途中で終了してしまって 目的のテスト対象のメソッドを実行するところまで辿りつけません・・・。 [お試しパターン1] Class c = TestManager.class; Constructor[] con = c.getDeclaredConstructors(); TestManager conIns = (TestManager)con[0].newInstance(); //ここで処理が終了してしまう [お試しパターン2] Class testClass = Class.forName("TestManager"); //ここで処理が終了してしまう Constructor[] TestManager = testClass.getDeclaredConstructors(); TestManager[0].setAccessible(true); Object conIns = TestManager[0].newInstance((Object[])null); TestManager test = (TestManager)conIns;

    • ベストアンサー
    • Java
  • 用語/newを伴わないコンストラクタの呼出=関数?

    コンストラクタを勉強しているのですが、「用語」「意味」が分からないので、教えてください ■質問1 ・いついかなる時でも、「コンストラクタ関数」=「コンストラクタ」=「関数」=「メソッド」なのでしょうか? ・例えば、「newをつけずに、コンストラクタを関数として呼ぶ」場合も、「コンストラクタを実行する」と言うのでしょうか? ■質問2 … 「new」付与による相違 ・「new」付与しないと、「コンストラクタ」内で「this」が指し示す対象が異なる(グローバルオブジェクトになってしまう)のだと思うのですが、それ以外に何か相違点はあるのでしょうか? ・「new」付与しないとオブジェクトが正しく生成されないので、不具合が生じる可能性がある? ■質問3 ・「new」を付けずに、オブジェクトを関数として実行するのは、例えばどういう使い方をするときなのでしょうか?

  • コンストラクタのオーバーロードについて

    class loo{ //フィールドの定義 int sland; //コンストラクタの定義1 loo(){ this.sland = 28; } //コンストラクタの定義2 loo(int sland){ this.sland = sland; } //メソッドの定義 void ken(){ System.out.println(this.sland); } } //mainメソッド class kkk{ public static void main(String args[]){ ---------------------------------------------- loo lo = new loo(); lo.ken(); lo.ken(100); ---------------------------------------------- } } コンストラクタのオーバーロードについて、伺いたいことがありますので掲載致しました。 今回は、kenメソッドを用いて変数slandに入っている値を表示するプログラムを作りたいと思っています。 コンストラクタのオーバーロードを利用するわけですが、プログラム実行後に 28 100 という風な出力結果を得ようと、上記のようなプログラミングを実施しました。 しかし、いざコンパイルをかけると java:27: ken() (loo 内) を (int) に適用できません lo.ken(100); ~ というエラーが表示されてしまいます。 ----でかっこってある部分に問題があるのはわかっているのですが、思うように結果を得ることができない状況です。 また、----の部分を、 loo lo = new loo(100); lo.ken(); lo.ken(); と、書き換えると出力結果は 100 100 と表示され、28が表示されなくなってしまいます。 お手数ですが、ご教授の程お願い致します。

専門家に質問してみよう