我对 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;
}
这里有两件事我不喜欢,在代码注释中用1.和2.标记,在有错误的行之前。(operator~
见1.)在 外部定义Apont
,如下:
template<typename T> static Apont<T>^% operator ~(T& valor)
{
return gcnew Apont<T>(valor);
}
我认为这个必须在外部定义Apont
,但我不确定。我不能很好地理解它产生的错误(当然,这些是在使用中,而不是在定义中)。
要设置Apont
引用的实例的值,我必须使用一个属性(标记为2.的行不起作用,仅在设置用法中有错误),Apont::Valor
它等效于 use *p
。我想做的是当我*p
用来获取或设置它指向的值时,!a
在Apont
. 这是Apont::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;
}
}