Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Взять значение из другого класса?


Автор: vdm 5.3.2008, 09:43
Есть класс А в нем есть public переменная значение которой я указываю сам. Есть класс Б в котором я должен взять значение из класса А, но когда беру значение, выдаёт то, которое устанавливается конструктором. Как поправить, чтобы выдавало то которое я сам уже установил? smile

Автор: andrew_121 5.3.2008, 09:45
Брось кусок кода...

Автор: vdm 5.3.2008, 10:02
Цитата(andrew_121 @ 5.3.2008,  09:45)
Брось кусок кода...

А без кода никак? опиши общий вариант, если знаешь ответ?

Автор: andrew_121 5.3.2008, 10:06
Вот тебе нужна помощь, а мне приходиться за тебя писать фрагмент кода который ты по каким-то причинам писать нехочешь.
Несправедливо...

Автор: Fazil6 5.3.2008, 12:29
Цитата(vdm @  5.3.2008,  09:02 Найти цитируемый пост)
А без кода никак? опиши общий вариант, если знаешь ответ?

 smile 
банальная ошибка в 17-й строке.

Автор: Mayk 5.3.2008, 12:32
Цитата(vdm @  5.3.2008,  14:02 Найти цитируемый пост)

А без кода никак? опиши общий вариант, если знаешь ответ? 

здесь можно только предполагать. а вдруг потом окажется что догадка не верна(а ведь оно так наверное и есть)? так что нужен отрывок кода на котором даная трабла воспроизводится. 

Автор: andrew_121 5.3.2008, 12:52
Тебе-то всего 4-и строки из каждого класса выдрать надо, не переживай, 8-м строк у тя никто не украдет !!!
 smile (Во МлЯ, IT-шные баньдюги.) smile 

Автор: orthrus 5.3.2008, 14:08
vdm,не выкладывай тут код, за ним все охотятся и обязательно его у тебя украдут smile Посмотри пару постов выше, там Fazil6 нашел ошибку smile 

Автор: vdm 5.3.2008, 14:59
Цитата(orthrus @ 5.3.2008,  14:08)
vdm,не выкладывай тут код, за ним все охотятся и обязательно его у тебя украдут smile Посмотри пару постов выше, там Fazil6 нашел ошибку smile

Да нет, ребята, не в том дело что украдут, просто какой именно вам отрывок нужен? smile там один класс в 600 строк, второй в 300, не хочу флудить. А если выкладывать так придётся и headers отдельно выложить.. какой именно отрывок нужен?

Автор: baldina 5.3.2008, 15:01
Код

struct A {
  int a_;
  A(int a) : a_(a);
};

struct B {
   foo (A& var, int newval)
   {
       std::cout << var.a_;
       var.a_ = newval;
    }
};

A a(10);
B b;
b.foo(a,5); // output: 10, a.a_ is 5 now
b.foo(a,0); // output: 5, a.a_ is 0 now


Автор: andrew_121 5.3.2008, 15:16
Код

struct A {
  int a_;
  A(int a) : a_(a);
};

struct B {
   foo (A& var, int newval)
   {
       var.a_ = newval;
       std::cout << var.a_;
    }
};

A a(10);
B b;
b.foo(a,5); // output: 10, a.a_ is 5 now
b.foo(a,0); // output: 5, a.a_ is 0 now

Разницы не замечаешь ?????.......

Добавлено через 3 минуты и 59 секунд
Цитата(vdm @  5.3.2008,  14:59 Найти цитируемый пост)
Да нет, ребята, не в том дело что украдут, просто какой именно вам отрывок нужен?  там один класс в 600 строк, второй в 300, не хочу флудить. А если выкладывать так придётся и headers отдельно выложить.. какой именно отрывок нужен?


Ну если в классе 600-от строк - то имеешь ты несчастье на свою голову.
Почитаю "Декомпозицию" -  в книжках по С/С++

Автор: vdm 5.3.2008, 15:23
В общем вопрос звучит так: 

class CW
{
public:

    CW(void);
               ~CW(void);
    long cvrshow(void)
    long cnr2;
}

long cvrshow(void) {
return cnr2;
}
при нажатии какойто кнопки присвоил значение cnr2

class CPlaneScene  
{
public:
    CPlaneScene();
    virtual ~CPlaneScene();
    CW p_CW;
}
long a = p_CW.cvrshow();

Но почемуто вызывает заново конструктор класса CW и значение теряется. Почему?

Автор: baldina 5.3.2008, 15:26
vdm, выложи 
  • описание переменной в классе А
  • фрагмент конструктора, где она инициализируется
  • описание функции класса В, куда передается объект типа А
  • строка функции В, где значение переменной используется
  • строка в программе (желательно что бы контекст был понятен), где вручную изменяется значение переменной
Добавлено через 2 минуты и 21 секунду
и укажи, что в каком классе определено (контекст). Вызов конструктора наводит на мысль о временном объекте.

Добавлено через 3 минуты и 7 секунд
Код

long a = p_CW.cvrshow();


вот это где и как вызывается?

Автор: andrew_121 5.3.2008, 15:37
Эй, это че-за детский сад.
long cnr2 - принадлежиn CW

Код

long cvrshow(void) {
   return cnr2; // а это что-за cnr2 ???
}


p_CW - принадлежит CPlaneScene
Код

long a = p_CW.cvrshow(); // p_CW - это ты откуда взял ???


Читай - Члены класса.

Автор: vdm 5.3.2008, 17:00
Цитата(baldina @ 5.3.2008,  15:26)
vdm, выложи 



  • описание переменной в классе А


  • фрагмент конструктора, где она инициализируется


  • описание функции класса В, куда передается объект типа А


  • строка функции В, где значение переменной используется


  • строка в программе (желательно что бы контекст был понятен), где вручную изменяется значение переменной


Добавлено @ 15:28
и укажи, что в каком классе определено (контекст). Вызов конструктора наводит на мысль о временном объекте.

Добавлено @ 15:29
Код

long a = p_CW.cvrshow();


вот это где и как вызывается?


Код


//header класса А:

class СW
{
public:
    long cnr2;
                long  Start(void);
                void  Set(void);
};

//Вот конструктор класса А

CW::CW(void)
{    
cnr2 = 3;
}

long CW::Start()
{
    return cnr2;
}

long CW::Set()
{
    cnr2 = 10;
}


//Класс С:
/* В хедере класса С прописываю хедер класса А */
//Header класса С:
class C1
{
public:

               CW c_CW;
};

//В классе С вызываем функцию, которая назначит значение для cnr2:

с_СW.Set();



//Класс Б:
/* В хедере класса Б прописываю хедер класса А */
//header класса Б:
class CPlaneScene  
{
public:
СW p_CW;
};

/* В классе вызываю Функцию класса СW чтобы получить значение cnr2 которое указал с помощью класса С */

//Но возвращает 3 а не 10. Почему?
long znak = p_CW.Start();



Автор: Alek86 5.3.2008, 17:12
значение переменной находится не в классе, а в объекте класса. чтобы разъяснить, чем объекты от классов отличаются, автору необходимо почитать учебники по С++

Автор: mes 5.3.2008, 17:18
Цитата(vdm @  5.3.2008,  17:00 Найти цитируемый пост)
class CPlaneScene  
{
public:
СW p_CW;
};


судя по префиксу p_  переменная p_CW должна быть объявлена как указатель
В таком случае если бы ты связал с объектом c_CW  (class C1) то тогда бы у тебя бы был доступ через обе переменные к одному и тому же объекту
а так у тебя два различных объекта и соответственно данные в них разные...

Добавлено через 1 минуту и 58 секунд
Цитата(Alek86 @  5.3.2008,  17:12 Найти цитируемый пост)
чтобы разъяснить, чем объекты от классов отличаются, автору необходимо почитать учебники по С++ 

присоединяюсь.. плюс почитать про указатели и понять разницу между ним и ссылкой.

Автор: baldina 5.3.2008, 17:23
vdm, у тебя две переменных типа CW: одна в экземпляре класса C1 другая - в CPlaneScene. Устанавливаешь значение в одной, а используешь в другой, потому и не работает. 
Если тебе надо, что бы С1 и CPlaneScene разделяли один объект типа CW, в одном из этих классов ты должен хранить не объект, а ссылку или указатель на общий объект. 
Если ты хочешь, что бы для всех экземпляров класса CW переменная cnr2 была лишь одна, объяви её как static. В этом случае обращение к ней будет не через объект, а через имя класса: CW::cnr2.

Автор: vdm 5.3.2008, 18:02
Цитата(baldina @ 5.3.2008,  17:23)
vdm, у тебя две переменных типа CW: одна в экземпляре класса C1 другая - в CPlaneScene. Устанавливаешь значение в одной, а используешь в другой, потому и не работает. 
Если тебе надо, что бы С1 и CPlaneScene разделяли один объект типа CW, в одном из этих классов ты должен хранить не объект, а ссылку или указатель на общий объект. 
Если ты хочешь, что бы для всех экземпляров класса CW переменная cnr2 была лишь одна, объяви её как static. В этом случае обращение к ней будет не через объект, а через имя класса: CW::cnr2.

//////  Если тебе надо, что бы С1 и CPlaneScene разделяли один объект типа CW, в одном из этих классов ты должен хранить не объект, а ссылку или указатель на общий объект. //////

Как это должно выглядить в моём случае, подскажи пожалуйста?

Автор: mes 6.3.2008, 01:39
Цитата(vdm @  5.3.2008,  17:00 Найти цитируемый пост)
class СW
{
public:
    long cnr2;
                long  Start(void);
                void  Set(void);
};

 
не в тему.. но глаз мозолит.. старайся не использовать данные в секции public:
запихивай их в приват... 


Цитата(vdm @  5.3.2008,  18:02 Найти цитируемый пост)
Как это должно выглядить в моём случае, подскажи пожалуйста?

вариантов масса ...вот один:

Код


struct Data {...};
class C1 
{ 
    public: 
        Data * GetPData () { return &m_data; }
   private:
      Data m_data;
};

class C2a
{
    public: 
        void SetPData (Data * pdata) { p_data =pdata; }  // связывает переменную с нужным объектом
   private:
      Data * p_data;   // звездочка после типа показывает что это указатель
};

class C2b // отличается от C2a только инициализацией указателя в конструкторе
{
  public:
       C3 (Data * pdata) : p_data (pdata) {  }
   private:
      Data * p_data;
};
....
// применение
C1 c1;
C2a  c2a;
c2a.SetPData (c1.GetPData());
C2b c2b(c1.GetPData());



в приведенный примере программисту самому придется следить за длиной жизни обших данных... 
(Чтоб указатель не показывал случайно на удаленный объект)
для более детального изучения проблемы все таки тебе придется почитать книжку , ))
так как расписывать здесь тоже самое нет смысла... только время потратится..

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

Автор: baldina 6.3.2008, 16:31
Цитата

Как это должно выглядить в моём случае, подскажи пожалуйста?

Это только ты знаешь. Это вопрос проектирования, а не программирования. Что бы сделать грамотно, нужно понять что за задачу ты решаешь, какова роль этой переменной. Для владельца классов, описание которых составляет от 300 до 600 строк это особенно актуально. Технику mes тебе показал.

Ход возможных рассуждений проиллюстрирую на примере:
Предположим CW это класс состояния некоего объекта,
С1 - тип объекта, к которому может быть применено состояние , CPlaneScene - класс, управляющий объектами типа С1, в т.ч. их состоянием.
Значит объект типа CPlaneScene имеет состояние и применяет их для объектов типа С1. Предположим, что у всех С1 состояние одинаковое, определяемое CPlaneScene. Тогда получается следующее:

Код

class CW {
   ...
public:
   CW() { SetState(0); }
   void SetState (long);
   long GetState () const;
   ...
};

class C1 {
   ...
   const CW* p_state;
public:
   C1 () : p_state(0) {}
   void SetStatePtr (const CW* p) { p_state = p; }
   void ClearStatePtr () { p_state = 0; }
   ...
};

class CPlaneScene {
  ...
  CW state;
  std::vector<C1*> vcp;

  void ApplyState (C1* c) const { c->SetStatePtr (&state); } 

public:
  void OnClick() { state.SetState (10); } // change state
  void AddC1 (C1 *pc) { vcp.push_back (pc); ApplyState (pc);  } 
  ...
};

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)