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


Автор: Экскалупатор 26.11.2010, 12:48
Добрый день. подскажите плиз, а то что то совсем не могу разобраться.
у меня есть класс который реализует бинарное дерево. но мне нужно сделать массив ссылок на эти классы(по задаче так). но когда я 
Код

//реализует дерево
class Node
{
private:
        char name[20];//имя
        char surName[20];//фамилия
        char patronymic[20];//отчество
        long dateOfBirth;//дата рождения в формате год-месяц-число
        Node *left;//левый узел-меньше текущего
        Node *right;//правый узел - больше текущего
        //идут разные методы
public:
    //конструктор по умолчанию
    Node()
    {
    }
    //конструктор с параметрами
    Node(char* newName, char* newSurName, char* newPatronymic, long newDateOfBirth)
    {
        strcpy(this->name, newName);
        strcpy(this->surName, newSurName);
        strcpy(this->patronymic, newPatronymic);
        this->dateOfBirth = newDateOfBirth;
        this->left = NULL;
        this->right = NULL;
    }
    //деструктор
    ~Node();
//разные методы
    //тут мне нужно сделать массив классов Node(что бы потом их можно было отсортировать по ключу отличному от того что использован в дереве
    void FindNode(std::string newSurName, long newDateOfBirth, int count)
    {
        Node *nodeMass[5];//так работает, но мне нужно что бы вместо 5 стояло count
        //вариант 2 - Node *nodeMass1 = new Node[count];//так не работает
        //вариант 3 - Node **nodes = new (Node*)[count];//так не работает,
    }
};

при варианте 2 выпадает
Error    14    error LNK2019: unresolved external symbol "public: __thiscall Node::~Node(void)" (??1Node@@QAE@XZ) referenced in function "public: void * __thiscall Node::`vector deleting destructor'(unsigned int)" (??_ENode@@QAEPAXI@Z)    BinaryTreeMain.obj    BinaryTree

и 
Error    15    fatal error LNK1120: 1 unresolved externals    J:\2 семестр\BinaryTree\Debug\BinaryTree.exe    1    BinaryTree
//вариант 3 выпадает 
Error     5     error C2337: 'count' : attribute not found     j:\2 семестр\binarytree\binarytree\binarytreemain.cpp     109     BinaryTree
и штук 50 подряд
Error     7     error C2143: syntax error : missing ';' before '}'     j:\2 семестр\binarytree\binarytree\binarytreemain.cpp     110     BinaryTree

как исправить? или как правильно объявить массив? находил в интернете примеры, должно работать по варианту 2, но не работает. пишу в VS2008

Автор: bsa 26.11.2010, 13:10
Error 14 говорит тебе человеческим языком, что у тебя объявлен деструктор, но не реализован. РЕАЛИЗУЙ ДЕСТРУКТОР.

Автор: Экскалупатор 26.11.2010, 14:36
bsa, точно. что то я не заметил. объясни еще такую штуку
Node *nodeMass1 = new Node[count]; создается массив объектов типа Node.(вызываются конструкторы и пр.)
а как быть если мне нужно массив указателей?(типа вариант 3).

Автор: mrbrooks 26.11.2010, 14:48
Node **nodeMass1 = new Node* [count];

Добавлено через 1 минуту и 21 секунду
хотя это дичь - надо юзать контейнеры stl и умные указатели (не auto_ptr, а что нибудь из boost)

Добавлено через 2 минуты и 26 секунд
хотя в VS 2008 - VC++ уже включены умные указатели

Автор: Экскалупатор 26.11.2010, 15:30
хм. а в чем разница между
Node **nodeMass1 = new Node* [count];
и
Node **nodeMass1 = new (Node*)[count];
???
первый вариант компилится, вариант со скобками не компилится. почему?

и еще. объясните почему такой трабл из за деструктора. ведь просто объект класса создавался, а массив нет.


Автор: WhKitten 26.11.2010, 17:14
Цитата(Экскалупатор @  26.11.2010,  15:30 Найти цитируемый пост)
Node **nodeMass1 = new (Node*)[count];

(Node*) это приведение в стиле C к типу Node*

Цитата(Экскалупатор @  26.11.2010,  12:48 Найти цитируемый пост)
Node *nodeMass[5];//так работает, но мне нужно что бы вместо 5 стояло count

Цитата(Экскалупатор @  26.11.2010,  15:30 Найти цитируемый пост)
объясните почему такой трабл из за деструктора. ведь просто объект класса создавался, а массив нет.

Node *nodeMass[5] массив из 5 указателей на Node. Конструктор не вызывается, память не выделяется, деструктор не вызывается.

Цитата(Экскалупатор @  26.11.2010,  12:48 Найти цитируемый пост)
//вариант 2 - Node *nodeMass1 = new Node[count];//так не работает

Вызывается конструктор count раз. Видимо разумно предполагается, что потом будет вызываться и деструктор, а его нет. По delete[] nodeMass1 должен быть вызван деструктор, причём опять count раз.

Автор: Экскалупатор 26.11.2010, 17:18
WhKitten, я имел ввиду что я могу написать(к примеру в main) Node* n = new Node();
я получаю указатель на объект. но не могу создать массив таких указателей. ругается на деструктор.(точнее сейчас могу, а когда деструктора не было то не мог)

Добавлено через 51 секунду
т.е. выражение Node **nodeMass1 = new Node* [count];
без деструктора не работало

Автор: Леопольд 27.11.2010, 09:35
Цитата(Экскалупатор @  26.11.2010,  17:18 Найти цитируемый пост)
без деструктора не работало 
Не в деструкторе, значит было дело. Такому коду вообще определение класса не нужно, только объявление.
Код
void foo(void)
{
    class Foo ** pp = new class Foo * [100];
    delete[] pp;
}

Автор: WhKitten 27.11.2010, 11:07
Я думаю он имел ввиду почему успешно линкуется:
Код

struct S {
    ~S();   
};

void main()
{
    S *s = new S;
}

а вроде почти аналогичный код не линкуется:
Код

struct S {
    ~S();   
};

void main()
{
    S *s = new S[1];
}

Автор: bsa 27.11.2010, 11:19
WhKitten, твой код даже не компилируется. В С++ необходимо, чтобы main возвращала тип int, а не void. По идее, второй вариант тоже должен компилироваться, отличий от первого практически нет. Возможно, просто где-то имеется delete...

Автор: WhKitten 27.11.2010, 11:28
http://msdn.microsoft.com/en-us/library/6wd819wh(v=VS.100).aspx, хоть этого и нет в стандарте. Если заменить void на int суть не изменится. Первый код будет успешно линковаться, а второй нет. smile Причём эти 8 строчек кода весь код необходимый, чтобы воспроизвести это в VS2010, т.е другого кода нет и delete нигде не вызывается.
Если я не ошибаюсь то это поведение описано в стандарте (пункт 5.3.4.16):
Цитата

If the new-expression creates an object or an array of objects of class type, access and ambiguity control are done for the allocation function, the deallocation function (12.5), and the constructor (12.1). If the new-expression creates an array of objects of class type, access and amiguity control are done for the destructor (12.4).

Но вопрос почему так лично для меня остаётся непонятным. smile Хотя конечно объявленный, но неопределённый деструктор для используемого класса ситуация почти невероятная. smile 

Автор: Леопольд 27.11.2010, 12:39
Цитата(WhKitten @  27.11.2010,  11:07 Найти цитируемый пост)
а вроде почти аналогичный код не линкуется:
В g++ всё линкуется, что выглядит логично, ведь деструктор нигде не вызывается...
Код
struct Foo
{
    ~Foo();
};
Foo * foo(void)
{
    Foo * pp = new Foo[1];
    return pp;
}
Цитата из стандарта, выглядит странно. Тоже не понятно, для чего такое требование...


"Плохой" g++, а-та-та по попе...
http://forum.sources.ru/index.php?act=ST&f=74&t=319555&view=findpost&p=2762929

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