Re[3]: Как такое написать по Сиплюсплюсному?
От: B0FEE664  
Дата: 24.03.25 08:29
Оценка:
Здравствуйте, kov_serg, Вы писали:

  Скрытый текст
BFE>>
BFE>>#include <stdio.h>

BFE>>struct I1 
BFE>>{ 
BFE>>    virtual void show()=0; 
BFE>>};
BFE>>struct I2 
BFE>>{ 
BFE>>    virtual void print()=0; 
BFE>>};

BFE>>struct A : I1,I2
BFE>>{
BFE>>    int x[3];
BFE>>    void show() { printf("show x0=%d\n",x[0]); }
BFE>>    void print() { printf("print x0=%d\n",x[0]); }
BFE>>    I1*  i1 = { this };
BFE>>    I2*  i2 = { this };
BFE>>};

BFE>>void fn(I1* i) { i->show(); }
BFE>>void fn(I2* i) { i->print(); }

BFE>>int main(int argc, char **argv) {
BFE>>    A a[1];
    a->>>x[0]=123;
BFE>>    fn(a->i1);
BFE>>    fn(a->i2);
BFE>>    return 0;
BFE>>}
BFE>>

BFE>>
_>Так можно было просто указатели преобразовать. Не заводя отдельных полей.
_>
_>I1* get_i1() { return this; }
_>

_>Хочется чего-то более структурированного

_>Слегка усложним. А если так:

_>
_>#include <stdio.h>

_>template<class A,class B>A*parent_of(B*self,B A::*t) { 
_>    return (A*)((char*)self-(char*)(&(((A*)0)->*t)));
_>}
_>template<class A,class B>A*parent_of(B*self,B(A::*t)[1]) { 
_>    return (A*)((char*)self-(char*)(&(((A*)0)->*t)));
_>}

_>struct I1 { virtual void show()=0; };
_>struct I2 { virtual void print()=0; };
_>struct I3 { virtual void next()=0; virtual void print()=0; };

_>struct A {
_>    int x[3];
_>    struct :I1 {
_>        A* parent() { return parent_of(this,&A::i1); }
_>        void show() { printf("show x0=%d\n",parent()->x[0]); }
_>    } i1[1];
_>    struct :I2 {
_>        A* parent() { return parent_of(this,&A::i2o); }
_>        void print() { printf("print  x0=%d\n",parent()->x[0]); }
_>    } i2o[1];    
_>    struct :I2 {
_>        A* parent() { return parent_of(this,&A::i2); }
_>        void print() { printf("print2 x0=%d\n",parent()->x[0]); }
_>    } i2[1];
_>    struct :I3 {
_>        A* parent() { return parent_of(this,&A::i3); }
_>        void next() { printf("next3\n"); }
_>        void print() { printf("print3 x0=%d\n",200-parent()->x[0]); }
_>    } i3[1];
_>};

_>void fn(I1* i) { i->show(); }
_>void fn(I2* i) { i->print(); }
_>void fn(I3* i) { i->print(); }

_>int main(int argc, char **argv) {
_>    A a[1];
    a->>x[0]=123;
_>    fn(a->i1);
_>    fn(a->i2);
_>    fn(a->i2o);
_>    fn(a->i3);
_>    return 0;
_>}
_>


Тупое решение "в лоб":
#include <stdio.h>

struct I1 { virtual void show()=0; };
struct I2 { virtual void print()=0; };
struct I3 { virtual void next()=0; virtual void print()=0; };

struct A {
    int x[3];
    struct II1:I1 {
        II1(A*p):parent(p){}; A* parent=nullptr;
        void show() { printf("show x0=%d\n",parent->x[0]); }
    } i1[1]{this};
    struct II2:I2 {
        II2(A*p):parent(p){}; A* parent=nullptr;
        void print() { printf("print  x0=%d\n",parent->x[0]); }
    } i2o[1]{this};
    struct II22:I2 {
        II22(A*p):parent(p){}; A* parent=nullptr;
        void print() { printf("print2 x0=%d\n",parent->x[0]); }
    } i2[1]{this};
    struct II3:I3 {
        II3(A*p):parent(p){}; A* parent=nullptr;
        void next() { printf("next3\n"); }
        void print() { printf("print3 x0=%d\n",200-parent->x[0]); }
    } i3[1]{this};
};

void fn(I1* i) { i->show(); }
void fn(I2* i) { i->print(); }
void fn(I3* i) { i->print(); }

int main(int argc, char **argv) {
    A a[1];
    a->x[0]=123;
    fn(a->i1);
    fn(a->i2);
    fn(a->i2o);
    fn(a->i3);
    return 0;
}



А зачем так издеваться над объектно ориентированным подходом?
И каждый день — без права на ошибку...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.