0

私はC++にかなり慣れていないので、演習として(そしておそらく最終的には.Netユーティリティ)、ポインターラッパーを実行しています(実際にはC++/CLIですが、これはC++にも当てはまります)。1.2.とマークされた行がコメントアウトされているApont場合、以下のテストが示すように、このポインター ラッパー ( と呼ばれる) は現在、ポインターと同じように動作します。

int main(array<System::String ^> ^args)
{
    double ia = 10; double ip = 10;
    double *p = &ip;                // pointer analogy
    Apont<double> ^a =
        gcnew Apont<double>(ia);    // equivalent to what's below, without errors
    a = ~ia;/* 1.       IntelliSense: expression must have integral or unscoped enum type
                        error C2440: '=' : cannot convert from 'double' to 'Utilidades::ComNativos::Apont<T> ^'
                        error C2171: '~' : illegal on operands of type 'double'*/
    Console::WriteLine("ip = {0}; *p = {1}; ia = {2}; !a = {3}", ip, *p, ia, !a);
    ia = 20; ip = 20;
    Console::WriteLine("ip = {0}; *p = {1}; ia = {2}; !a = {3}", ip, *p, ia, !a);
    *p = 30;        // pointer analogy
    a->Valor = 30;  // does exacly what's below, without errors
    !a = 30;/* 2.   IntelliSense: expression must be a modifiable lvalue
                    error C2106: '=' : left operand must be l-value */
    Console::WriteLine("ip = {0}; *p = {1}; ia = {2}; !a = {3}", ip, *p, ia, !a);
    //a->Dispose();
    Console::ReadKey();
    p = nullptr;
    return 0;
}

ここで気に入らない点が 2 つあります。コード コメントのエラーのある行の前に1.2.でマークされています。( 1.operator~を参照) は、以下の の外側で定義されます。Apont

template<typename T> static Apont<T>^% operator ~(T& valor)
{
    return gcnew Apont<T>(valor);
}

これは の外で定義する必要があると思いますApontが、よくわかりません。それが生成するエラーをよく理解できません(もちろん、これらは定義ではなく使用にあります)。

のインスタンスが参照する値を設定するには、プロパティを使用する必要があります ( 2.Apontとマークされた行は機能せず、設定の使用方法のみにエラーがあります) 、これは use と同等です。私がやりたいのは、それが指す値を取得または設定するために使用するのと同じように、 で同じ効果を使用することです。の現在の定義は次のとおりです。Apont::Valor*p*p!aApontApont::operator!()

T operator !()
{
    return Valor;
}

2. (それぞれのエラーの前のコード内のコメント) でわかるように、値の設定には機能しません。多分私は参照を返す必要がありますか?おそらくクラス外で、同じ名前の別の演算子を作成しますか? いくつかのオプションを試しましたが、同様のエラーが発生し、さらに混乱しました。

問題は、&(この場合は~)のように動作する演算子と、 *(この場合!は逆参照のための) のように動作する演算子を作成するにはどうすればよいかということApont::Valorです。

property T Valor
{
    T get()
    {
        if (pointer != nullptr)             
            return *pointer;
        else if (eliminado && ErroSeEliminado) // means "disposed && ErrorIfDisposed"
            throw gcnew ObjectDisposedException("O objeto já foi pelo menos parcialmente eliminadao.");
        else if (ErroSeNulo) // means "ErrorIfNull"
            throw gcnew NullReferenceException();
        else
            return 0;
// don't worry, this is not default behavior, it is returned only if you want to ignore all errors and if the pointer is null
    }
    void set(T valor)
    {
        *pointer = valor;
    }
}
4

2 に答える 2

1

私があなたのコードを正しく理解していれば、オペレーター~がポインターラッパーのコピーを返し、オペレーター!が逆参照として機能することを望みますか?

この場合、コピー コンストラクターを呼び出すクラスoperator ~内で単項を定義できます。Apontまた、operator !値を割り当てたい場合は、実際に参照を返す必要があります。

次の C++ コードは、何をしたいのかを定義していると思います (名前を に変更ApontしましたA)。

#include <iostream>

template<typename T>
struct A {
    T* payload;

    A(T *ptr)
        :payload(ptr) {}
    A(const A&other)
        :payload(other.payload) {}

    T& operator !(){
        return *payload;
    }

    T* operator ~(){
        return payload;
    }
};

int main(){
#define PRINT(X) std::cerr << #X << " = " << X << std::endl
    int i = 0;
    PRINT(i);

    A<int> a(&i);
    !a = 1;
    PRINT(i);

    A<int> b = ~a;
    !b = 2;
    PRINT(i);
}

上記のコードの出力は次のとおりです。

i = 0
i = 1
i = 2

あなたのコメントによると、オペレーター!がラップされたポインターとまったく同じように動作するようにしたいとおっしゃいました。そうすることはできますが、構文が変更され、それを逆参照して新しい値を割り当てる必要があります (ポインターであるため...)。つまり、次のようなものです:

#include <iostream>

template<typename T>
struct A {
    T* payload;

    A(T *ptr): payload(ptr) {}

    // this now behaves like accessing the wrapped pointer directly
    T*& operator !(){
        return payload;
    }
};

int main(){
#define PRINT(X) std::cerr << #X << " = " << X << std::endl
    int i = 0;
    int j = 999;
    PRINT(i);

    A<int> a(&i);
    *(!a) = 1;  // note the change of syntax here
    PRINT(*!a); // and here

    !a = &j;    // but now you can change the wrapped pointer through the operator
    PRINT(*!a);
}
于 2013-04-20T14:01:55.423 に答える