2013-02-22 8 views
2

Я пытаюсь создать иерархию классов, каждый класс содержит вложенную структуру, содержащую данные.Указатель на тип объекта

////////Class.h//////////////////////////// 
#ifndef _CLASS_H_ 
#define _CLASS_H_ 
#include <stdio.h> 

class A{//Base 
    protected: 
    struct dataA{ 
     int v1, v2; 
    }; 
    public: 
    A(); 
    virtual void met1(); 
    dataA * const set; 
    const dataA * const get; 
}; 

class B : public A{//Child1 
    protected: 
    struct dataB : public dataA{ 
     int v3, v4; 
    }; 
    public: 
    B(); 
    virtual void met2(); 
    dataB * const set; 
    const dataB * const get;  
}; 

class C : public B{//Child2 
    struct dataC : public dataB{ 
     int v5, v6; 
    }; 
    public: 
    C(); 
    void met3(); 
    dataC * const set; 
    const dataC * const get; 
}; 
#endif 
////////Class.cpp/////////////////////////// 
#include "Class.h" 

A::A() : set(new dataA), get(set) { 
    this->set->v1 = -1; 
    this->set->v2 = -1; 
} 

void A::met1() { 
    printf("%i, %i", this->get->v1, this->get->v2);//PRINTS "-1, -1" 
} 

B::B() : A(), set(new dataB), get(set) { 
    this->set->v3 = -1; 
    this->set->v4 = -1; 
} 

void B::met2() { 
    printf("%i, %i", this->get->v1, this->get->v2);//An attempt to access C's "get" variable, PRINTS "-1, -1" 
} 

C::C() : B(), set(new dataC), get(set) { 
    this->set->v5 = -1; 
    this->set->v6 = -1; 
} 

void C::met3() { 
    printf("%i, %i", this->get->v1, this->get->v2);//PRINTS "2, 3" 
} 
///////main.cpp//////////////////////////////// 
#include "Class.h" 

int main() { 
    C memb; 
    memb.set->v1 = 2; 
    memb.set->v2 = 3; 
    printf("%i, %i", memb.get->v1, memb.get->v2);//PRINTS "2, 3" 
    memb.met2();//PRINTS "-1, -1" 
    return 0; 
} 

enter image description here Итак, что я пытался сделать это после того, как объявить элемент типа С, чтобы получить доступ к наследуемой функции из B, который имеет доступ к данным структуры языка C. Указатель void не будет выполнять задание, поскольку он не может указывать на типы объектов. Я пробовал передать адрес C в B, хотя они оба разных типа. Прежде всего, если я получаю доступ к v1 из основного блока, если я установил для него значение, как показано в примере, я получаю правильное значение - значение, которое я установил. Однако, если я попытаюсь получить доступ к одной и той же переменной, но вместо этого из класса B, она печатает значение, как если бы оно не было установлено раньше, кроме как из конструктора. Поэтому я пытаюсь создать ссылку из класса B в структуру данных класса C - в структуру данных класса B данных родительского класса B. Код примера не был скомпилирован. С уважением!

+0

Возможно, код, который компилирует может помочь. В 'A :: dataA' нет элемента данных' var1', поэтому разыменование 'this-> get-> var1' в инструкции printf недопустимо. Это не единственная проблема (очевидно). – WhozCraig

+0

@WhozCraig Я считаю, что все должно быть хорошо – user203432

+0

Вы понимаете, что ваши комментарии относительно «prints -1, -1» и т. Д. Неверны? Я немного смущен в отношении того, чего вы пытаетесь достичь, и каков ваш реальный вопрос. –

ответ

2

Я уверен, что это близко к тому, что вы хотите, хотя я должен сказать вам, что мне нужно принять душ после его написания. Есть тонна вещей в этом я бы не стал, но ...

#include <cstdio> 
#include <cstdlib> 
using namespace std; 

class A{//Base 
protected: 
    struct dataA 
    { 
     int v1, v2; 
    } * const data; 

    A(dataA* const p) 
     : data(p) 
    { 
     p->v1=-1; 
     p->v2=-1; 
    }; 

public: 
    virtual void met1() 
    { 
     printf("%i, %i", get()->v1, get()->v2); 
    } 

    const dataA * const get() const { return data; } 
    dataA * const set() const { return data; } 
}; 

class B : public A {//Child1 
protected: 
    struct dataB : public dataA 
    { 
     int v3, v4; 
    } * const data; 

    // protected constructor 
    B(dataB * const p) 
     : A(p), data(p) 
    { 
     p->v3 = 0; 
     p->v4 = 0; 
    }; 

public: 
    virtual void met2() 
    { 
     printf("%i, %i, %i, %i", get()->v1, get()->v2, get()->v3, get()->v4); 
    } 

    const dataB * const get() const { return data; } 
    dataB * const set() const { return data; } 
}; 

class C : public B 
{ 
    struct dataC : public dataB 
    { 
     int v5, v6; 
    } * const data; 

public: 
    C() : B(new dataC), 
    data(static_cast<dataC*>(B::data)) 
    { 
     data->v5 = 0; 
     data->v6 = 0; 
    }; 

    ~C() 
    { 
     // note, the pointers in B and A are left 
     // dangling after this is done. 
     delete data; 
    } 

    virtual void met2() 
    { 
     printf("%i, %i, %i, %i, %i, %i", 
       get()->v1, get()->v2, 
       get()->v3, get()->v4, 
       get()->v5, get()->v6); 
    } 

    const dataC * const get() const { return data; } 
    dataC * const set() const { return data; } 
}; 


///////main.cpp//////////////////////////////// 

int main() { 
    C memb; 
    memb.set()->v1 = 2; 
    memb.set()->v2 = 3; 
    printf("%i, %i\n", memb.get()->v1, memb.get()->v2); 
    memb.met2(); 
    return 0; 
} 

Выход


Update

OP хотел видеть это без члены get() и set(), используя только переменные-члены. Опять же, просто отвратительный, но здесь вы идете:

#include <cstdio> 
#include <cstddef> 

class A{//Base 
protected: 
    struct dataA 
    { 
     int v1, v2; 
    }; 
    dataA * const set; 
    const dataA * const get; 

    A(dataA* const p) 
     : get(p), set(p) 
    { 
     p->v1=-1; 
     p->v2=-1; 
    }; 

public: 
    virtual void met1() 
    { 
     printf("%i, %i\n", get->v1, get->v2); 
    } 
}; 

class B : public A {//Child1 
protected: 
    struct dataB : public dataA 
    { 
     int v3, v4; 
    }; 
    dataB * const set; 
    const dataB *const get; 


    // protected constructor 
    B(dataB * const p) 
     : A(p), set(p), get(p) 
    { 
     p->v3 = 0; 
     p->v4 = 0; 
    }; 

public: 
    virtual void met2() 
    { 
     printf("%i, %i, %i, %i\n", get->v1, get->v2, get->v3, get->v4); 
    } 
}; 

class C : public B 
{ 
    struct dataC : public dataB 
    { 
     int v5, v6; 
    }; 
public: 
    dataC * const set; 
    const dataC * const get; 

    C() : B(new dataC), 
     set(static_cast<dataC *const>(B::set)), 
     get(static_cast<const dataC *const>(B::get)) 
    { 
     set->v5 = 0; 
     set->v6 = 0; 
    } 

    ~C() 
    { 
     // note, the pointers in B and A are left 
     // dangling after this is done. 
     delete set; 
    } 

    virtual void met2() 
    { 
     printf("%i, %i, %i, %i, %i, %i\n", 
       get->v1, get->v2, 
       get->v3, get->v4, 
       get->v5, get->v6); 
    } 
}; 


///////main.cpp//////////////////////////////// 

int main() { 
    C memb; 

    memb.set->v1 = 2; 
    memb.set->v2 = 3; 

    printf("%i, %i\n", memb.get->v1, memb.get->v2); 
    memb.met2(); 

    B& obj = memb; 
    obj.met1(); 
    obj.met2(); 

    return 0; 
} 

Выход

2, 3 
2, 3, 0, 0, 0, 0 
2, 3 
2, 3, 0, 0, 0, 0 
+0

Очень ценим! Хотя, есть ли способ упростить синтаксис и использовать set и получить переменные? – user203432

+1

@ user203432 да, но это было бы еще более ужасно. – WhozCraig

+0

Аг, ладно, спасибо в любом случае, угадайте, что это будет делать. Эта маленькая деталь удерживала меня, может быть, через неделю или две, рад, что это частично закончилось :) – user203432