0

関数を呼び出してコンストラクターをプライベートに保つにはどうすればよいですか?クラスを静的にすると、コンパイラーがコンストラクターを呼び出すために使用するオブジェクト名を宣言する必要があります。コンストラクターがプライベートの場合は宣言できません(オブジェクトも無関係になります)。これが私が使おうとしているコードです(コンパイルできません):

後でオブジェクトを追加する前に多くのチェックを行い、送信されたすべての変数が一意でない場合は新しいオブジェクトを作成するのではなく、以前のオブジェクトを変更するため、コンストラクターをプライベートに保ちたいと思います。

#include <iostream>
#include <fstream>
#include <regex>
#include <string>
#include <list>
#include <map>

using namespace std;
using namespace tr1;

class Referral
{
public:
    string url;
    map<string, int> keywords;

    static bool submit(string url, string keyword, int occurrences)
    {
        //if(Referrals.all.size == 0){
        //  Referral(url, keyword, occurrences);
        //}
    }

private:
    list<string> urls;

    Referral(string url, string keyword, int occurrences)
    {
        url = url;
        keywords[keyword] = occurrences;
        Referrals.all.push_back(this);
    }
};

struct All
{
    list<Referral> all;
}Referrals;

int main()
{
    Referral.submit("url", "keyword", 1);
}
4

4 に答える 4

6

プライベートコンストラクターと静的ファクトリメソッドを持つことの何が問題になっていますか?

class Example {
  Example() { ... }
public:
  static Example CreateExample() {
    return Example();
  }
};
于 2009-09-03T20:53:15.503 に答える
2

あなたのコードに基づいて、あなたが狙っているのはシングルトンmainだと思います。これは次のようになります。

class Referral
{
private:
    Referral()
    {
        //...
    }

public:
    static Referral& instance()
    {
        static Referral instance_s;
        return instance_s;
    }

    bool submit(string url, string keyword, int occurrences)
    {
        //...
    }
};

次に、呼び出しは次のmainようになります。

int main()
{
    Referral::instance().submit("url", "keyword", 1);
}

もう1つの可能性は、紹介のリストを保持しようとしていることです。この場合、紹介のリストとを使用して、struct探していることを実行できます。

struct Referral
{
    Referral(string url, string keyword, int occurrences) :
        url_m(url), keyword_m(keyword), occurrences_m(occurrences)
    { }

    string url_m;
    string keyword_m;
    int    occurrences_m;
};

typedef std::vector<Referral> ReferralSet;

次に、呼び出しは次のmainようになります。

int main()
{
    ReferralSet set;

    set.push_back(Referral("url", "keyword", 1));
}
于 2009-09-03T21:02:47.197 に答える
1

まず、Submitを静的関数にする必要があります。その後、あなたはただ言うことができます

Referral::Submit( url, keyword, occurrences );

紹介インスタンスを作成せずに。

次に、送信機能では、ほとんどすぐに消える一時的な参照オブジェクトのみを作成します。おそらくあなたがしたいのは、newで動的にインスタンスを作成することです。これをどのように管理するかによっては、リストにプッシュするコードを[送信]に移動することをお勧めします。

最後に、紹介インスタンスのリストを、現在の状態ではなく、静的メンバー変数にします。

(また、これらの文字列引数を参照で渡すことはおそらく良い考えです。)

于 2009-09-03T21:08:16.873 に答える
1

コード全体に多少の臭いがありますが、質問とは関係のないわずかな変更を加えるだけで、コードを機能させることができます。

コンパイルするために、正規表現インクルード(C ++ 0xをサポートするコンパイラーを使用していません)と「usingnamespacetr1」を削除しました。Referralグローバルオブジェクトの定義の後にコンストラクターの実装を移動します。変更 。静的メソッドを参照する場合のmain関数の::の場合。

// changes...
//#include <regex>
...
//using namespace tr1;
...
class Referral { 
...
    Referral(string url, string keyword, int occurrences); // added ; moved the implementation bellow the Referrals variable definition
...
struct All  {
...
} Referrals;

// added constructor implementation here (Referrals global must be defined before use):
Referral::Referral(string url, string keyword, int occurrences)
{
   url = url;
   keywords[keyword] = occurrences;
   Referrals.all.push_back(*this); // added dereference, this is of type Referral*, not Referral
}

int main()
{
   Referral::submit("url","keyword",1);
}

さて、設計の観点から、コードには悪臭があります。本当にReferralオブジェクトを追加するグローバルリストが必要な場合は、それをReferralクラスのプライベート静的属性にして、もう少し制御できるようにすることを検討してください(Referralクラスのメソッドのみがコンテンツを壊す可能性があります)。すべての属性を非公開にし、ユーザーコードに必要な機能へのアクセサーのみを提供します(ほとんどの場合、読み取り専用アクセスで十分です)。コンストラクターで初期化リストを使用し、クラス定義に表示されるのと同じ順序ですべてのメンバーを初期化します。

それをすべて修正しても、まだ匂いがあります。静的関数はクラスのインスタンスを作成しますが、コンストラクターはそれ自体をマップに含めるものです(??)コンストラクターがマップと対話しなかった場合はもう少し意味があり、submit()メソッドは作成しますオブジェクトをリストに含めます...

自分がやろうとしていることを表現することで恩恵を受けるかもしれないと思います。ここの多くの人々は、デザインの選択とその理由の両方であなたを助けてくれます。

于 2009-09-03T21:42:47.413 に答える