Как работают функции интерпретаторов, написанные в классе C ++ в - PullRequest
3 голосов
/ 31 марта 2010

Я работаю над проектом о структурах данных. Во-первых, я написал все в основном, но это звучит как C. Но, как я узнал, я пытался продумать ООП и делать как можно меньше в моих методах main ().

Я реализовал некоторую работу в своем классе, такую ​​как add, delet, find.It слишком легко реализовать.

class ARB
{
        private:
                struct BT
                {
                        int data;
                        BT *l;
                        BT *r;
                };
                struct BT *p;
       public
                ARB();
                ~ARB();
                void del(int n);
                void add(int n); 
};

    void ARB::del(int num)
{
//The code ,don't care about it 

  };  

main()
{
// 
    BTR T;
    T.add(3);
    T.add(5);

};

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

STACK ARB::MyFunct(BT* p)
{
// The code don't care about it 
}

Как я могу применить его в основной программе

main()
{
// 
    BT T;
    T.add(3);
    T.add(5);
    STACK S;
    BT* p
    S=T.MyFunct(p); // error C2664 cannot convert parametre 1

};

** упоминание: я реализую класс STACK

Ответы [ 4 ]

0 голосов
/ 31 марта 2010

Здесь есть несколько вопросов. С одной стороны, add () является функцией-членом ARB, а не BT. И BT является частным подклассом ARB, поэтому к нему нельзя получить доступ из main (). p является закрытым членом ARB (как и должно быть), но на самом деле он должен быть прямой переменной, а не указателем, поэтому он будет автоматически создан и уничтожен с помощью ARB. Таким образом, p никогда не инициализируется, и нет никакого способа сделать это вне ARB.

Здесь я предполагаю, что ARB использует свой внутренний BT p для внутренней памяти, поэтому реализации add () и del () работают на p, и MyFunct () должен взять этот BT и сгенерировать стек от него. Если это так, MyFunct () не должен принимать никаких параметров и просто ссылаться на p напрямую.

Так что main () будет выглядеть примерно так:

ARB arb;
arb.add(3)
arb.add(5)
STACK s = arb.myFunct(); // which should maybe be makeStack() or such

Все это предполагает, что я правильно вывел ваши намерения здесь.

0 голосов
/ 31 марта 2010

Полагаю, вы пытаетесь пройти по дереву и построить из него стек? Я не понимаю, почему вы проходите мимо p. Из вашего примера похоже, что вы просто создали указатель на BT объект, а затем пытаетесь передать его внутрь.

Похоже, в этом есть смысл:

S=T.MyFunct();

Не могли бы вы использовать this для построения своего дерева? Наверное, я не уверен, что ты пытаешься сделать.

Предполагая, что вы пытаетесь реализовать функцию для объекта BT, которая преобразует BT в стек, вам не нужно ничего передавать (поскольку MyFunct является функцией-членом BT). У вас уже есть доступ к дереву в вашей функции-члене, поэтому все, что вам нужно сделать, это пройтись по дереву и построить стек.

Примечание: Мой C ++ довольно ржавый.

0 голосов
/ 31 марта 2010

Прежде всего, это может помочь, если строки 5 и 6 будут изменены.

/ * КОД: внутри основного
1 BT T;
2 T.add (3);
3 T.add (5);
4 STACK S;
5 BT * p
6 S = T.MyFunct (p); // ошибка C2664 не может преобразовать параметр 1
* /

Строка 5: BT * p; -> BT * p = & T;
Строка 6: S = T.MyFunct (p) -> S = ARB :: MyFunct (p);
Теперь, предполагая, что MyFunct делает то, что предполагает, он должен работать. Основная проблема с программой заключалась в том, что указатель p не был инициализирован, что уменьшало параметр до void. Кроме того, я предполагаю, что MyFunct не имеет объектных отношений, поэтому нет смысла ссылаться на T в этом случае. Вот почему я бы предложил вместо более поздней версии.

0 голосов
/ 31 марта 2010

Похоже, это может быть неправильно задан оператор копирования классов STACK, например:

class STACK {
public:
    ...
    STACK& operator=(STACK& right); // copy assign
    ...
};

в этом случае конструктор копирования требует, чтобы он мог изменить right, но STACK, возвращаемый из ARB::MyFunct(), является временным и не может быть изменен. Попробуйте изменить конструктор копирования на STACK(STACK const& right), чтобы C ++ знал, что вы его не измените. Если вы используете компилятор, поддерживающий ссылки на R-значения (например, Visual Studio 2010), тогда вы можете определить «конструктор перемещения», а также конструктор копирования:

class STACK {
public:
    STACK& operator=(STACK const& right); // copy assign: note 'const'
    STACK& operator=(STACK&& right); // move assign: note no 'const', double '&'.
    ...
};

Это будет вызываться только с временными значениями, которые можно изменять.

Те же правила применяются к конструкторам:

class STACK {
public:
    STACK();
    STACK(STACK const& right); // copy construct
    STACK(STACK&& right); // move construct
    STACK& operator=(STACK const& right); // copy assign
    STACK& operator=(STACK&& right); // move assign
    ...
};

int main() {
    STACK S = T.MyFunct(p); // move construct S (right side is temporary)
    S = T.MyFunct(p); // move assign S (right side is temporary)

    STACK K = S; // copy construct K (right side is not temporary)
    K = S; // copy assign K (right side is not temporary)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...