gpt4 book ai didi

c++ - 在 C++ 类中具有公共(public)属性

转载 作者:IT老高 更新时间:2023-10-28 23:10:44 27 4
gpt4 key购买 nike

我如何在 C++ 类中拥有属性,就像在 C# 类中一样。

我不想拥有 getter 和 setter 方法。

最佳答案

您可以使用类似于 Jon 建议的解决方案,但使用运算符重载保留普通 C++ 语义。我稍微修改了 Jon 的代码如下(代码后面有解释):

#include <iostream>

template<typename T>
class Accessor {
public:
explicit Accessor(const T& data) : value(data) {}

Accessor& operator=(const T& data) { value = data; return *this; }
Accessor& operator=(const Accessor& other) { this->value = other.value; return *this; }
operator T() const { return value; }
operator T&() { return value; }

private:
Accessor(const Accessor&);


T value;

};

struct Point {
Point(int a = 0, int b = 0) : x(a), y(b) {}
Accessor<int> x;
Accessor<int> y;
};

int main() {
Point p;
p.x = 10;
p.y = 20;
p.x++;
std::cout << p.x << "," << p.y << std::endl;

p.x = p.y = 15;
std::cout << p.x << "," << p.y << std::endl;

return 0;
}

我们重载 operator= 以保留通常的赋值语法,而不是类似函数调用的语法。我们使用强制转换运算符作为“getter”。我们需要第二个版本的 operator= 来允许在 main() 中进行第二种赋值。

现在您可以添加到访问器的构造函数指针,或者更好的 - 仿函数 - 以任何方式调用 getter/setter 对您来说似乎是正确的。下面的例子假设 setter 函数返回 bool 表示同意设置新值,getter 可以在它退出时修改它:

#include <iostream>
#include <functional>
#include <cmath>

template<typename T>
class MySetter {
public:
bool operator()(const T& data)
{
return (data <= 20 ? true : false);
}
};

template<typename T>
class MyGetter {
public:
T operator()(const T& data)
{
return round(data, 2);
}

private:
double cint(double x) {
double dummy;
if (modf(x,&dummy) >= 0.5) {
return (x >= 0 ? ceil(x) : floor(x));
} else {
return (x < 0 ? ceil(x) : floor(x));
}
}

double round(double r, int places) {
double off = pow(10.0L, places);
return cint(r*off)/off;
}
};

template<typename T, typename G = MyGetter<T>, typename S = MySetter<T>>
class Accessor {
public:
explicit Accessor(const T& data, const G& g = G(), const S& s = S()) : value(data), getter(g), setter(s) {}

Accessor& operator=(const T& data) { if (setter(data)) value = data; return *this; }
Accessor& operator=(const Accessor& other) { if (setter(other.value)) this->value = other.value; return *this; }
operator T() const { value = getter(value); return value;}
operator T&() { value = getter(value); return value; }

private:
Accessor(const Accessor&);

T value;

G getter;
S setter;

};

struct Point {
Point(double a = 0, double b = 0) : x(a), y(b) {}
Accessor<double> x;
Accessor<double> y;
};

int main() {
Point p;
p.x = 10.712;
p.y = 20.3456;
p.x+=1;
std::cout << p.x << "," << p.y << std::endl;

p.x = p.y = 15.6426;
std::cout << p.x << "," << p.y << std::endl;

p.x = p.y = 25.85426;
std::cout << p.x << "," << p.y << std::endl;

p.x = p.y = 19.8425;
p.y+=1;
std::cout << p.x << "," << p.y << std::endl;

return 0;
}

但是,正如最后一行所示,它有一个错误。返回 T& 的 cast 运算符允许用户绕过 setter,因为它使他们可以访问私有(private)值。解决此错误的一种方法是实现您希望访问器提供的所有运算符。例如,在以下代码中,我使用了 += 运算符,并且由于我删除了强制转换运算符返回引用,因此我必须实现一个 operator+=:

#include <iostream>
#include <functional>
#include <cmath>

template<typename T>
class MySetter {
public:
bool operator()(const T& data) const {
return (data <= 20 ? true : false);
}
};

template<typename T>
class MyGetter {
public:
T operator() (const T& data) const {
return round(data, 2);
}

private:
double cint(double x) const {
double dummy;
if (modf(x,&dummy) >= 0.5) {
return (x >= 0 ? ceil(x) : floor(x));
} else {
return (x < 0 ? ceil(x) : floor(x));
}
}

double round(double r, int places) const {
double off = pow(10.0L, places);
return cint(r*off)/off;
}
};

template<typename T, typename G = MyGetter<T>, typename S = MySetter<T>>
class Accessor {
private:
public:
explicit Accessor(const T& data, const G& g = G(), const S& s = S()) : value(data), getter(g), setter(s) {}

Accessor& operator=(const T& data) { if (setter(data)) value = data; return *this; }
Accessor& operator=(const Accessor& other) { if (setter(other.value)) this->value = other.value; return *this; }
operator T() const { return getter(value);}

Accessor& operator+=(const T& data) { if (setter(value+data)) value += data; return *this; }

private:
Accessor(const Accessor&);

T value;

G getter;
S setter;

};

struct Point {
Point(double a = 0, double b = 0) : x(a), y(b) {}
Accessor<double> x;
Accessor<double> y;
};

int main() {
Point p;
p.x = 10.712;
p.y = 20.3456;
p.x+=1;
std::cout << p.x << "," << p.y << std::endl;

p.x = p.y = 15.6426;
std::cout << p.x << "," << p.y << std::endl;

p.x = p.y = 25.85426;
std::cout << p.x << "," << p.y << std::endl;

p.x = p.y = 19.8425;
p.y+=1;
std::cout << p.x << "," << p.y << std::endl;

return 0;
}

您必须实现所有将要使用的运算符。

关于c++ - 在 C++ 类中具有公共(public)属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2559900/

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