gpt4 book ai didi

c++ - 指针包装器 : dereference operator

转载 作者:行者123 更新时间:2023-11-28 03:18:31 25 4
gpt4 key购买 nike

我是 C++ 的新手,作为练习(也许最终是 .Net 实用程序),我正在做一个指针包装器(实际上是在 C++/CLI 中,但这也适用于 C++)。这个指针包装器(称为 Apont)目前的行为就像一个指针,正如下面的测试所示,如果行标记为 1.2. 被注释掉了:

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. 的行不起作用,设置使用有错误only), Apont::Valor,相当于使用 *p。我想做的是,当我使用 *p 获取 或设置 它指向的值时,使用 !a 相同对 Apont 的影响。这是 Apont::operator!() 的当前定义:

T operator !()
{
return Valor;
}

正如您在 2. 中看到的(在代码中的注释,在相应的错误之前),它不适用于设置值。也许我应该返回引用?制作另一个同名的运算符,也许在类(class)之外?我尝试了几种选择,但是,我遇到了类似的错误,结果更加困惑。

问题是:我怎样才能使操作符的行为像 &(在本例中为 ~)和行为像 *(在这种情况下,!,用于取消引用,但它的行为类似于 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;
}
}

最佳答案

为了清楚起见,让我在一个新的答案中回顾一下。

解决 ! 运算符很简单,正如我在之前的回答中所说,只需添加一个引用即可。

因此对于运算符~,目标是让它表现得像&运算符,并调用指针包装类的构造函数。

我认为这是不可能的。用户定义的对象当然是可能的,但我认为不可能为内置类型重载一元运算符。因此,根据您的喜好,提供三种解决方案:

第一个完全符合您的要求,但会破坏原始类型:

#include <iostream>

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

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

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

// this will not work for primary types
template<typename T>
A<T> operator ~(T &b){
return A<T>(&b);
}

struct B{
int test;
};

int main(){
B b; b.test = 4;

A<B> a;
a = ~b; // I think this is what you want
std::cerr << (!a).test << std::endl;

// this does not work
//int i = 4;
//A<int> a;
//a = ~i;
}

第二种解决方案:使用复合赋值运算符。优点是副作用很小,缺点是这不是很直观,可能会破坏您心中的美好设计。

#include <iostream>

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

A() : payload(NULL){}

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

template<typename T>
A<T>& operator &=(A<T> &a, T& b){ // should be friend of the above
a.payload = &b;
return a;
}

int main(){
int i = 3;
A<int> a;
a &= i;
std::cerr << !a << std::endl;
}

第三种解决方案:重载基本赋值运算符。这样写起来更直观,但有很多副作用:

#include <iostream>

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

A() : payload(NULL){}

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

A<T>& operator = (T & b) {
payload = &b;
return *this;
}
};

int main(){
int i = 3;
A<int> a;
a = i;
std::cerr << !a << std::endl;
}

有人可能有劫持原始类型运算符的解决方案,但我想不出任何简单的解决方案。

关于c++ - 指针包装器 : dereference operator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16120882/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com