¿Puede una clase tener miembros de datos virtuales?

5 minutos de lectura

avatar de usuario de vandanak
vandanak

class Base{  
    public:  
        void counter();   
    ....   
}

class Dervied: public Base{  
    public:  
        ....  
}

void main()  
{  
     Base *ptr=new Derived;  
     ptr->counter();  
}

Para identificar que el puntero de la clase base apunta a la clase derivada y usa una función miembro derivada, usamos “virtual”.

Del mismo modo, ¿podemos hacer que los miembros de datos derivados sean “virtuales”? (el miembro de datos es público)

  • la pregunta obvia es por qué? ¿Cuál es la necesidad de ello? puede haber formas alternativas de resolver ese problema.

    – Naveen

    13 de septiembre de 2010 a las 8:36

  • Usted (por lo general) no debe usar miembros de datos públicos de todos modos y buscar accesores en su lugar; por lo tanto, ni siquiera debería necesitar esto.

    -Georg Fritzsche

    13 de septiembre de 2010 a las 8:39


  • Por favor agregue la palabra virtual en algún lugar de su pseudocódigo.

    – Patatas

    13 de septiembre de 2010 a las 9:10

  • @Georg: Tonterías, los miembros de datos públicos tienen su lugar.

    – John Dibling

    13 de septiembre de 2010 a las 16:26

  • @andre: Solo una idea: los miembros de datos virtuales podrían usarse para mezclar o tipear patos. Cuando 2 clases A y B ambos definen un virtual int countentonces una clase derivada que hereda A y B podría llevar solo una (ya que es virtual) count miembro. Para esto, las clases base deben tener un diseño compatible o el compilador podría crear automáticamente captadores/establecedores que sincronicen el valor de ambas clases base.

    – Tino

    25 de enero de 2014 a las 20:24

avatar de usuario de liaK
liaK

virtual es un Especificador de función

De documentos estándar,

7.1.2 Especificadores de funciones Los especificadores de funciones sólo se pueden utilizar en declaraciones de funciones. especificador de función: explícito virtual en línea

Entonces no hay nada llamado Miembro de datos virtuales.

Espero eso ayude…

  • Sí… ayudó. Pasó por “publib.boulder.ibm.com/infocenter/comphelp/v7v91/…” también…

    – vandanak

    13 de septiembre de 2010 a las 11:03

  • ¿Qué pasa con la herencia virtual? class Foo : public virtual Bar no me parece una declaración de función…

    – tomi.lee.jones

    12 de junio de 2015 a las 14:24

avatar de usuario de mmonem
mmonem

No, pero puede crear una función virtual para devolver un puntero a lo que llama miembro de datos virtuales

  • Probablemente no pueda hacer eso, ya que puede conducir a una violación de acceso.

    – C–

    28 de septiembre de 2019 a las 5:23

  • Requeriría un cuidado extra

    – mmonem

    28 de septiembre de 2019 a las 9:54

No, en C++ no hay miembros de datos virtuales.

Creo que no, pero ¿podrías simularlo usando getters y setter virtuales, tal vez?

Avatar de usuario de Chubsdad
gordito

Para identificar que el puntero de la clase base apunta a la clase derivada y usa una función miembro derivada, usamos “virtual”.

Eso no es correcto. Hacemos funciones virtuales para permitir que las clases derivadas proporcionen una implementación diferente a la que proporciona la base. No se utiliza para identificar que el puntero de la clase base apunta a la clase derivada.

Del mismo modo, ¿podemos hacer que los miembros de datos derivados sean “virtuales”? (el miembro de datos es público)

Solo las funciones miembro no estáticas pueden ser virtuales. Los miembros de datos no pueden ser.

Aquí está un enlace con algo más de información sobre eso

  • “Hacemos funciones virtuales para permitir que las clases derivadas proporcionen una implementación diferente a la que proporciona la base”. No del todo, ya obtienes eso cuando creas una clase derivada y escribes una función con el mismo nombre que una en una superclase. Qué virtual lo que hace es permitirle convertir un objeto en una de sus superclases pero seguir usando la implementación de la clase derivada para funciones virtuales. (En otras palabras, C++ usa despacho estático para funciones normales y despacho dinámico para funciones virtuales).

    – JAB

    20 noviembre 2013 a las 16:30


Avatar de usuario de Igor Zevaka
Igor Zevaka

No, porque eso rompería la encapsulación en una miríada de formas inesperadas. Cualquier cosa que desee lograr se puede hacer con atributos protegidos y/o funciones virtuales.

Además, las funciones virtuales son un método de despacho (es decir, seleccionar qué función se va a llamar), en lugar de seleccionar una ubicación de memoria correspondiente al atributo del miembro.

  • “Hacemos funciones virtuales para permitir que las clases derivadas proporcionen una implementación diferente a la que proporciona la base”. No del todo, ya obtienes eso cuando creas una clase derivada y escribes una función con el mismo nombre que una en una superclase. Qué virtual lo que hace es permitirle convertir un objeto en una de sus superclases pero seguir usando la implementación de la clase derivada para funciones virtuales. (En otras palabras, C++ usa despacho estático para funciones normales y despacho dinámico para funciones virtuales).

    – JAB

    20 noviembre 2013 a las 16:30


Avatar de usuario de Lagrange.el.Ciencia
Lagrange.el.Ciencia

Una clase no puede tener un miembro virtual, consulte, por ejemplo, esta respuesta. Sin embargo, puede tener algo similar usando punteros, herencia y polimorfismo en tiempo de ejecución.

En el siguiente fragmento, defino el prototipo para un modelo geométrico. shapeque tiene un area método. los picture la clase tiene un miembro shape* s;
y los métodos de eso shape señalado por s son utilizados por picture::show(). En esta configuración no es deseable tener una instancia de picture antes de una implementación real de un shape se ha dado, por lo que forzamos picture ser abstracto agregando una función virtual ficticia picture::make_real().

// prototypes
class shape
{
    public:
    virtual double area() = 0; // to be defined later
};
class picture
{
    protected:
    shape* s;
    
    virtual void make_real() = 0; // force picture to be abstract
    
    public:
    picture(shape* ptr):
        s{ptr}
    {}
    
    void show()
    {
        std::cout << s->area() << '\n';
    }
};

A continuación, implementamos un shape llamó square y un picture escribe
square_picture que (literalmente) tiene un square shape.

// actual implementation

class square : public shape
{
    double len;
    
    public:
    square(double l):
        len{l}
    {}
     
     double area() override
    {
        return len*len;
    }
};



class square_picture : public picture
{
    void make_real() override {} // square_picture is not abstract
    
    public:
    square_picture(double l):
        picture{new square{l}}
    {}
    
    ~square_picture()
    {
        delete s;
    }
};

La clase square_picture se puede probar con el siguiente fragmento

int main()
{
    square_picture A{2.0};
    A.show();
    
    //picture B{nullptr}; // error: picture is abstract
    return 0;
}

que salidas:

4

¿Ha sido útil esta solución?