2016-11-06 4 views
1

次は、thisに直接関連しています。私が望むのは、メモリを節約するために一度に1つのクラスだけを呼び出すことができるようにすることですが、後でGUIを追加する予定であるため、クラスを呼び出すこともできますドロップダウンメニュー(たとえば)をクリックします。メモリを節約するために、一度に1つのクラスのみクラスをインスタンス化してください。

私は、組成物を作ってみましたが、これは出てきたものです:

#include <iostream> 

class Power 
{ 
private: 
    double m_x; 
public: 
    Power() {std::cout<<"Power\n";} 
    Power(double x): m_x {x} {std::cout<<"Power("<<x<<")\n";} 
    ~Power() {std::cout<<"~Power\n";} 
    const double getX() const { return m_x; } 
}; 

class Scanner 
{ 
private: 
    Power m_power; 
public: 
    Scanner() {std::cout<<"Scanner\n";} 
    Scanner(const Power &p): m_power {p} {std::cout<<"Scanner("<<&p<<")\n";} 
    void print() {std::cout<<"x="<<m_power.getX()<<'\n';} 
}; 

class Printer 
{ 
private: 
    Power m_power; 
public: 
    Printer() {std::cout<<"Printer\n";} 
    Printer(const Power &p): m_power {p} {std::cout<<"Printer("<<&p<<")\n";} 
    void print() {std::cout<<"x="<<m_power.getX()<<'\n';} 
}; 

class Copier // if Copier is to be used for "unification", will "public" be needed? 
{ 
private: 
    Scanner *m_s; 
    Printer *m_p; 
    int m_i; 
public: 
    Copier() {std::cout<<"Copier\n";} 
    Copier(const Power &p, int i): m_i {i} 
    { 
     if (i) 
      m_s = new Scanner(p); 
     else 
      m_p = new Printer(p); 
     std::cout<<"Copier("<<&p<<","<<i<<")\n"; 
    } 
    void print() { std::cout << (m_i ? m_s->getX() : m_p->getX()) << '\n'; } 
}; 

int main(int argc, char *argv[]) 
{ 
    Scanner *s {new Scanner(Power(2.3))}; 
    s->print(); 
    Printer *p {new Printer(Power(3.14))}; 
    p->print(); 
    s->print(); // here, both *s and *p exist, both use memory 
    // this comes after considering adding class Copier 
    Copier *c {new Copier(Power(1.618), 0)}; 
    c->print(); 
    c = new Copier(Power(2.718), 1); 
    c->print(); 
    return 0; 
} 

は少しのためにCopierを無視します。それは、私はそれを使用することができ、これが何であるか出てくる:

Power(2.3) 
Scanner(0x7ffc80d98c10) 
~Power 
x=2.3 
Power(3.14) 
Printer(0x7ffc80d98c20) 
~Power 
x=3.14 
x=2.3 

(メジャー)の問題は今、メモリ内の複数のオブジェクトがあるということです*sありますし、あなたが見ることができるよう、*pありますxすることができますpeは両方とも3.142.3で印刷されました。 2つ以上のクラス(私が行っているクラス)を持っていれば、クラスを呼び出すことができ、それぞれがメモリを使います。それは私が欲しいものではありません。

一度に1つのクラスのみを呼び出すことはできますが、余分なリセットや削除を呼び出す必要はありません。私はそれに別のクラスを追加することを考えました。Copierを参照してください。しかし、私はstd::unique_ptrを使用することはできません。コード内のソリューションは、非常に醜いだけでなく、機能しません。さらに、それはクレイジーのようなコンストラクタを呼び出します。

私は(c++14を必要としていること、そして私はむしろ、いくつかのより大きな安全マージンを維持するだろうが、私はあまりにも、それと一緒に暮らすことができ)std::make_uniqueで、シンプルな機能でstd::unique_ptrを使用してみました。

std::unique_ptr<Power> call(const Power &p, const int &i) 
{ 
    if (i) 
     return std::make_unique<Printer>(p); 
    else 
     return std::make_unique<Scanner>(p); 
} 

私はこれを行う方法がわからない:それは(私がz->print()を呼び出す場合、それは'class Power' has no member 'print'言います)Powerを指すので、それはまた、動作しません。手短に言えば、クラスScanner,Printer、およびその他の存在するクラスは、コンピューティングの方法で一意の1つのタスクのみを実行する専用クラスであり、すべてがPower(自分自身以外のもの)の共通変数を使用します。私は、共通変数を各クラスに移動するのは非常に効果的だとは思っていません。なぜなら、コードを膨らませるだけで、同じ変数を何度も何度も繰り返すのではなく、 、それを使用する "(私の言葉ではない、これは本当ですか?)。次に、これらのクラスをインスタンス化できるようにしたいと思いますが、一度に1つのクラスのみをアクティブにして、メモリを確保してください。

例として、1つのクラスが1milの値の配列を作成し、次に別のクラスが1milの異なる値を作成すると仮定します。インスタンス化されたクラスと同じくらい何度もメモリに配列があるとします。私はそれを望んでいない。 Copierの目的は、(条件に基づいて)一度に1つのクラスだけを呼び出すことでした。ジョブは完了しましたか?別の人に電話して、前にやったことを忘れて、新たに始めてください。リストから選択するなど、1つのウィジェットのみを呼び出すことができるようにするには、& goをクリックします。これは後で追加されます。愚かな間違いだった


、私はコピー&ペーストした後public ...を削除するのを忘れました。私はまた、Copierでコードを試してみましたが、まだコンパイルされていませんが、m_xは、ScannerPrinterのポインタをCopierの中の2つの非常に醜い解決策でも空にしています。


まあ、いくつかの試行の後、私はので、私はそれが継承を意味していても、戻って私のオリジナルのアイデアに行くために考えたかったことはありませんでした。だから私は、私は少しより多くの意味を作るために名前を変更したコードのこの作品、思い付いた(?):

#include <iostream> 

class Garage 
{ 
protected: 
    double m_x; // gas, tires, etc, that all cars use, reside in the Garage 
public: 
    Garage() {std::cout<<"Garage\n";} 
    virtual ~Garage() {std::cout<<"~Garage\n";} 
}; 

class Audi: virtual public Garage 
{ 
public: 
    Audi() {std::cout<<"Audi\n";} 
    void f(const double &x) { m_x=x; std::cout<<"Audi::f("<<x<<")\n";} 
}; 

class Bmw: virtual public Garage 
{ 
public: 
    Bmw() {std::cout<<"Bmw\n";} 
    void f(const double &x) { m_x=x; std::cout<<"Bmw::f("<<x<<")\n";} 
}; 

class Driver: public Audi, public Bmw 
{ 
private: 
    double m_y; // report of driving, based on m_x 
public: 
    Driver() {std::cout<<"Driver\n";} 
    Driver(const double &x, int i) 
    { 
     if (i) 
      Bmw::f(x); 
     else 
      Audi::f(x); 
     m_y = -m_x; 
     std::cout<<"Driver("<<x<<","<<i<<")\n"; 
    } 
    void print() { std::cout << "x=" << m_x << ", y=" << m_y << '\n'; } 
}; 

int main(int argc, char *argv[]) 
{ 
    Driver *d {new Driver(1.618, 0)}; 
    d->print(); 
    d = new Driver(0.618, 1); 
    d->print(); 
    // even iteration works now 
    delete d; 
    d = nullptr; // to be sure it's dead(?) 
    for (int i=0; i<2; ++i) 
    { 
     d = new Driver(3.14, i); 
     d->print(); 
    } 
    return 0; 
} 

さて、これは動作しますが、私は悪いコードに新しいレコードを設定する気持ちを持っています例。私はこのために私を打ち出したり、すべての間違いを指摘したり、同じ結果を達成するためにはどうしたらいいのでしょうか。それでも、私が望むように動作するように見えても、必要なものだけではなく、すべての枝ですべてのコンストラクタを呼び出します。私は実現しました(私の謝罪)Driverm_xをさらに使用し、そのm_y(これはコードが少し違う理由です)を使用する責任もあることを忘れていました。


私はこのコードを維持するのに固定し、またはその他のいない午前ことを指摘したいと思い、私がいる限り、私は私の目的に達するよう、変更し、適応する喜んで。しかし、私は初心者なので、あまりにも多くの組み合わせを作ることはできないので、自分が理解してもらうために私が到達した結果を提示して残します。上記のプログラムは、実行時には、私が望むものを与え、ループを作る可能性もあります。後でGUIで簡単に使うことができます。名前はそのままで、構成上最も意味があります。Garageは-Bmwです。これは私が試したものでしたが、私が望むものを得ることができませんでした。したがって、これが継承を使用していて、Audiが-Garageであることを意味しなくても、最初の試練を構成するために名前を付けました。これを投稿する私の主な理由は、私がプログラムにしたいことを示すことです。 main()で起こることはGUIで使用されるでしょう、私はQtを考えています。これは3つの主要なOSすべてで実行したいからです。したがって、一度に1台の車を呼び出すことができ、メモリ内に古くなったオブジェクトを持たずに以前の情報を保存できるようになると、m_x * nr_of_carsだけで作業するのがずっと楽になります。あなたが本当にtagged unionで何をしたいおそらく

std::unique_ptr<Power> 
call(const Power &p, const int &i) { 
    if (i) 
    return std::unique_ptr<Power>(new Printer(p)); 
    else 
    return std::unique_ptr<Power>(new Scanner(p)); 
} 

+0

は、なぜあなたは、両方の電源から派生し、電源メンバーを持っているのですか? – Mat

+3

このデザインは継承、多重継承でも​​いっぱいです。スキャナとプリンタは電源ではないので、電源があります。基底クラスが "マシン"のようなものだったら意味があります。 "メモリを節約する"のようなことを心配する前に、オブジェクト指向の設計に関する本を読むことを開始する必要があります。 –

+0

@Mat私はhttp://www.learncpp.com/cpp-tutorial/102-composition/を参考にしています(下のPoint2DとCreatureを参照)。 #ChristianHackl Garage、Scanner、Printer to Audi、BMW、Copier to Driverに変更すると、構図の意味が変わりますか? –

答えて

0

は、いくつかのstd::unique_ptrコンストラクタを使用してください。 rule of fiveに従ってください。インスピレーションについてはthisを参照してください。

+0

私はコンストラクタと外部でそれを試しましたが、 'm_x'はまだ空になります。 –

1

これを行う方法の1つです。ここで

{ // scope begins 
    Printer p; // note, no pointers 
    p.print(); 
} // scope ends, p is gone 

我々は、表示されたオブジェクトを持って一度一つのことをして、そして消えます。ここで

は別の

boost::variant<Printer,Scaner,Copier> psc(Printer()); 
psc.get<Printer>().print(); 
psc = Scaner(); // the printer is gone 
+0

'std :: variant'はなぜですか? –

+0

もし私がそれを行うなら、ウィジェットを使って後でこのようなことをどのように呼び出すことができますか? –

+1

@ChristianHackl C++ 17はまだここにはいません。 –

関連する問題