resueltos - programacion orientada a objetos c++ ejemplos
Variables de clase: acceso público de solo lectura, pero acceso privado de lectura/escritura (11)
pero temp.x = 5; ¿No permitido?
Esto no está permitido en el fragmento publicado porque, de todos modos, se declara como privado y solo se puede acceder al alcance de la clase.
Aquí están pidiendo acceso
cout << temp.x << endl;
pero aquí no para-
int myint = temp.x;
Esto suena muy contradictorio.
Whoopee, no trabajando en esa biblioteca de socket por el momento. Estoy tratando de educarme un poco más en C ++.
Con las clases, ¿hay alguna forma de convertir una variable de solo lectura para el público, pero leer + escribir cuando se accede de forma privada? por ejemplo, algo como esto:
class myClass {
private:
int x; // this could be any type, hypothetically
public:
void f() {
x = 10; // this is OK
}
}
int main() {
myClass temp;
// I want this, but with private: it''s not allowed
cout << temp.x << endl;
// this is what I want:
// this to be allowed
temp.f(); // this sets x...
// this to be allowed
int myint = temp.x;
// this NOT to be allowed
temp.x = myint;
}
Mi pregunta, condensada, es cómo permitir el acceso completo a x
desde dentro de f()
pero el acceso de solo lectura desde cualquier otro lugar, es decir, int newint = temp.x;
permitido, pero temp.x = 5;
¿No permitido? como una variable const, pero escribible desde f()
...
EDITAR: Olvidé mencionar que planeo regresar una instancia de vector grande, usar una función getX () solo haría una copia de eso y no es realmente óptimo. Podría devolverle un puntero, pero eso es mala práctica iirc.
PD: ¿Dónde publicaría si solo quiero mostrar básicamente mi conocimiento de los punteros y preguntar si está completo o no? ¡Gracias!
Debe hacer que el miembro sea private
y proporcionar un método getter public
.
Es posible que desee imitar las properties de C # para el acceso (dependiendo de lo que vaya, del entorno previsto, etc.).
class Foo
{
private:
int bar;
public:
__declspec( property( get = Getter ) ) int Bar;
void Getter() const
{
return bar;
}
}
Escribe una función getter pública.
int getX(){ return x; }
Esto puede hacer lo que quieras.
Si desea una variable de solo lectura pero no desea que el cliente tenga que cambiar la forma en que accede a ella, intente con esta clase de plantilla:
template<typename MemberOfWhichClass, typename primative>
class ReadOnly {
friend MemberOfWhichClass;
public:
inline operator primative() const { return x; }
template<typename number> inline bool operator==(const number& y) const { return x == y; }
template<typename number> inline number operator+ (const number& y) const { return x + y; }
template<typename number> inline number operator- (const number& y) const { return x - y; }
template<typename number> inline number operator* (const number& y) const { return x * y; }
template<typename number> inline number operator/ (const number& y) const { return x / y; }
template<typename number> inline number operator<<(const number& y) const { return x <<y; }
template<typename number> inline number operator>>(const number& y) const { return x >> y; }
template<typename number> inline number operator^ (const number& y) const { return x ^ y; }
template<typename number> inline number operator| (const number& y) const { return x | y; }
template<typename number> inline number operator& (const number& y) const { return x & y; }
template<typename number> inline number operator&&(const number& y) const { return x &&y; }
template<typename number> inline number operator||(const number& y) const { return x ||y; }
template<typename number> inline number operator~() const { return ~x; }
protected:
template<typename number> inline number operator= (const number& y) { return x = y; }
template<typename number> inline number operator+=(const number& y) { return x += y; }
template<typename number> inline number operator-=(const number& y) { return x -= y; }
template<typename number> inline number operator*=(const number& y) { return x *= y; }
template<typename number> inline number operator/=(const number& y) { return x /= y; }
template<typename number> inline number operator&=(const number& y) { return x &= y; }
template<typename number> inline number operator|=(const number& y) { return x |= y; }
primative x;
};
Ejemplo de uso:
class Foo {
public:
ReadOnly<Foo, int> x;
};
¡Ahora puede acceder a Foo.x, pero no puede cambiar Foo.x! ¡Recuerde que también necesitará agregar operadores bit a bit y unarios! Esto es solo un ejemplo para comenzar
Hay una forma de hacerlo con una variable miembro, pero probablemente no sea la manera aconsejable de hacerlo.
Tener un miembro privado que sea de escritura, y una variable de miembro público de referencia que alias a un miembro de su propia clase.
class Foo
{
private:
Bar private_bar;
public:
const Bar& readonly_bar; // must appear after private_bar
// in the class definition
Foo() :
readonly_bar( private_bar )
{
}
};
Eso te dará lo que quieres.
void Foo::someNonConstmethod()
{
private_bar.modifyTo( value );
}
void freeMethod()
{
readonly_bar.getSomeAttribute();
}
Lo que puedes hacer y lo que debes hacer son asuntos diferentes. No estoy seguro de que el método que acabo de describir sea popular y pase muchas revisiones de código. También aumenta innecesariamente sizeof (Foo) (aunque en una pequeña cantidad), mientras que un simple "getter" de acceso no lo haría, y puede ser inline, por lo que tampoco generará más código.
La única manera que conozco de otorgar acceso de solo lectura a los miembros de datos privados en una clase de c ++ es tener una función pública. En su caso, le gustará:
int getx() const { return x; }
o
int x() const { return x; }
int x() const { return x; }
.
Al hacer que un miembro de datos sea privado, por defecto lo hace invisible (es decir, sin acceso) al alcance fuera de la clase. En esencia, los miembros de la clase tienen acceso de lectura / escritura al miembro de datos privados (suponiendo que no especifique que es const
). friend
de la clase tienen acceso a los miembros de datos privados.
Consulte here y cualquier buen libro de C ++ sobre especificadores de acceso.
Por supuesto que puede:
class MyClass
{
int x_;
public:
int x() const { return x_; }
};
Si no desea hacer una copia (para enteros, no hay sobrecarga), haga lo siguiente:
class MyClass
{
std::vector<double> x_;
public:
const std::vector<double>& x() const { return x_; }
};
Esto no hace ninguna copia. Devuelve una referencia a const .
Si bien creo que una función getter que devuelve const T&
es la mejor solución, puede tener casi exactamente la sintaxis que pidió:
class myClass {
private:
int x_; // Note: different name than public, read-only interface
public:
void f() {
x_ = 10; // Note use of private var
}
const int& x;
myClass() : x_(42), x(x_) {} // must have constructor to initialize reference
};
int main() {
myClass temp;
// temp.x is const, so ...
cout << temp.x << endl; // works
// temp.x = 57; // fails
}
EDITAR : con una clase proxy, puede obtener con precisión la sintaxis que solicitó:
class myClass {
public:
template <class T>
class proxy {
friend class myClass;
private:
T data;
T operator=(const T& arg) { data = arg; return data; }
public:
operator const T&() const { return data; }
};
proxy<int> x;
// proxy<std::vector<double> > y;
public:
void f() {
x = 10; // Note use of private var
}
};
temp.x
parece ser una int
lectura-escritura en la clase, pero una int
solo lectura en main
.
Tendría que dejarlo en privado y luego hacer una función para acceder al valor;
private:
int x;
public:
int X()
{
return x;
}
Una solución simple, como Rob, pero sin contructor:
class myClass {
private:
int m_x=10; // Note: different name than public, read-only interface
public:
const int& x=m_x;
};
int main() {
myClass temp;
// temp.x is const, so ...
cout << temp.x << endl; // works
// temp.x = 57; // fails
}
Es como un metodo, pero mas corto. Pregunta interesante ... algo así como medida const bool miembro; puede ahorrar muchos getters ... pero no sé idiomas con esta característica ...