Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблемы со статич. свойствами, +всё ломается при использовании шаблонов 
:(
    Опции темы
wowka19
Дата 18.1.2012, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



Вот класс:


node.h
Код

#ifndef NODE_H
#define NODE_H

/*template <typename T>*/ class Node {
    private:
    Node * prevNode;
    Node * nextNode;
    void init();
    //T * item;

    public:
    Node();
    Node(const Node &);
    ~Node();
    static Node * head;
    static Node * tail;

    Node * getPrevNode();
    Node * getNextNode();
};

#endif // NODE_H



node.cpp
Код

#include "node.h"

Node * Node::head = 0;
Node * Node::tail = 0;

void Node::init() {
    if (head == 0) {
        head = this;
        prevNode = 0;
    } else {
        tail->nextNode = this;
        prevNode = tail;
    }
    tail = this;
    nextNode = 0;
}

Node::Node() {
    //item = new T;
    init();
}

Node::Node(const Node & rNode) {
    //item = new T(*rNode.item);
    init();
}

Node::~Node() {
    if (prevNode == 0) {
        head = nextNode;
    } else {
        prevNode->nextNode = nextNode;
    }

    if (nextNode == 0) {
        tail = prevNode;
    } else {
        nextNode->prevNode = prevNode;
    }
}

Node * Node::getPrevNode() {
    return prevNode;
}

Node * Node::getNextNode() {
    return nextNode;
}


Во-первых это работает только когда статические свойства инициализируются в реализации класса, а не в main() как положено (учился по учебнику Либерти):
если в 
main() {
    Node * Node::head = 0;
    Node * Node::tail = 0;
}
то компилятор : 
C:\Users\Alega\Documents\codeblocks\laba02\main.cpp|9|error: invalid use of qualified-name 'Node::head'|
C:\Users\Alega\Documents\codeblocks\laba02\main.cpp|10|error: invalid use of qualified-name 'Node::tail'|

Во-вторых при применении механизма шаблонов (если всё раскомментировать) компилятор ругается на эти статические свойства в node.cpp:
C:\Users\Alega\Documents\codeblocks\laba02\node.cpp|3|error: expected constructor, destructor, or type conversion before '*' token|
C:\Users\Alega\Documents\codeblocks\laba02\node.cpp|4|error: expected constructor, destructor, or type conversion before '*' token|
C:\Users\Alega\Documents\codeblocks\laba02\node.cpp|6|error: 'template<class T> class Node' used without template parameters|

Помогите разобраться. Уже второй день сижу, несколько раз переписывал всё с нуля!
PM MAIL   Вверх
mes
Дата 18.1.2012, 19:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



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

Добавлено через 1 минуту и 30 секунд
редкий компилятор поддерживает экспорт шаблонов, поэтому определять всю поднаготную шаблонного класса нужно в хидере..

Добавлено через 2 минуты и 33 секунды
Цитата(wowka19 @  18.1.2012,  18:36 Найти цитируемый пост)
когда статические свойства инициализируются в реализации класса, а не в main() 

должны быть определены как за пределами класами, так и за пределами функции (в том числе маин)

Добавлено через 3 минуты и 56 секунд
Цитата(wowka19 @  18.1.2012,  18:36 Найти цитируемый пост)
Во-вторых при применении механизма шаблонов 

ну так template <typename T> нужно перед каждым определением добавлять.. 




--------------------
PM MAIL WWW   Вверх
rumit7
Дата 18.1.2012, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 16.6.2011

Репутация: нет
Всего: 7



Цитата(wowka19 @ 18.1.2012,  19:36)
Во-первых это работает только когда статические свойства инициализируются в реализации класса, а не в main() как положено (учился по учебнику Либерти):


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

Цитата(wowka19 @ 18.1.2012,  19:36)
Помогите разобраться. Уже второй день сижу, несколько раз переписывал всё с нуля!


Как-то так должно быть чтобы хотя бы компилировалось..

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

Это сообщение отредактировал(а) rumit7 - 18.1.2012, 20:19
PM MAIL   Вверх
wowka19
Дата 18.1.2012, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



Вот это немного не понял:

Цитата(mes @  18.1.2012,  19:42 Найти цитируемый пост)
редкий компилятор поддерживает экспорт шаблонов, поэтому определять всю поднаготную шаблонного класса нужно в хидере..


и вот этого:


Цитата(mes @  18.1.2012,  19:42 Найти цитируемый пост)
Цитата(wowka19 @  18.1.2012,  18:36 )
когда статические свойства инициализируются в реализации класса, а не в main() 

должны быть определены как за пределами класами, так и за пределами функции (в том числе маин)


Можно на моем примере код показать?

И еще пару сопутствующих вопросов:
1. Почему компилятор выдает ошибку:
 "C:\Users\Alega\Documents\codeblocks\laba02\node.cpp|3|error: 'NULL' was not declared in this scope|"
когда я пишу
Node<T> * Node<T>::head = NULL // так даже вроде правильнее (по идеологии)
вместо
Node<T> * Node<T>::head = 0 //все-таки 0 - это число, а NULL - указатель (какой-то там)
???

2. Объясните в чем различия между a, b и c:
char * a = "hello";
char * b = new char[6]; b[0] = 'h', b[] = 'e', b[] = 'l', b[] = 'l', b[] = 'o', b[] = '\0';
char c[6] = {'h', 'e', 'l', 'l', 'o', '\0'};
Просто хочу иметь четкие и исчерпывающие понятия о данных типах. Такие вещи не объясняются в книжках (подобным образом).

3. Очень частые warnings:
warning: deprecated conversion from string constant to 'char*'
можно ли на них забить? и как от них избавиться?

Это сообщение отредактировал(а) wowka19 - 18.1.2012, 20:59
PM MAIL   Вверх
mes
Дата 18.1.2012, 22:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



если строку надо изменять, создавайте массив
  char c [] = "hello" // или что то же самое  {'h', 'e', 'l', 'l', 'o', '\0'};
иначе можно 
  const char * c =  "hello";
но не делайте 
 char * c =  "hello"

Добавлено через 3 минуты и 47 секунд
Цитата(wowka19 @  18.1.2012,  19:32 Найти цитируемый пост)
 а не в main() 

это не правильно :
Цитата(wowka19 @  18.1.2012,  18:36 Найти цитируемый пост)
Код

int main() {
    Node * Node::head = 0;
    Node * Node::tail = 0;

}

нужно вне функции, т.е. так :
Код

Node * Node::head = 0;
Node * Node::tail = 0;

main() {
}

в первом примере в принципе у Вас так и написано...



--------------------
PM MAIL WWW   Вверх
wowka19
Дата 19.1.2012, 07:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



Цитата(mes @  18.1.2012,  22:32 Найти цитируемый пост)
но не делайте 
 char * c =  "hello"

Почему?


Цитата(mes @  18.1.2012,  22:32 Найти цитируемый пост)
если строку надо изменять, создавайте массив
  char c [] = "hello" // или что то же самое  {'h', 'e', 'l', 'l', 'o', '\0'};
**********
но не делайте 
 char * c =  "hello"

А разве это не одно и тоже?

В общем объясните пожалуйста ранее поставленный вопрос:
Цитата(wowka19 @  18.1.2012,  20:32 Найти цитируемый пост)
2. Объясните в чем различия между a, b и c:
char * a = "hello";
char * b = new char[6]; b[0] = 'h', b[] = 'e', b[] = 'l', b[] = 'l', b[] = 'o', b[] = '\0';
char c[6] = {'h', 'e', 'l', 'l', 'o', '\0'};
Просто хочу иметь четкие и исчерпывающие понятия о данных типах. Такие вещи не объясняются в книжках (подобным образом).




Это сообщение отредактировал(а) wowka19 - 19.1.2012, 07:23
PM MAIL   Вверх
borisbn
Дата 19.1.2012, 09:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(wowka19 @  18.1.2012,  20:32 Найти цитируемый пост)
2. Объясните в чем различия между a, b и c:
char * a = "hello";
char * b = new char[6]; b[0] = 'h', b[] = 'e', b[] = 'l', b[] = 'l', b[] = 'o', b[] = '\0';
char c[6] = {'h', 'e', 'l', 'l', 'o', '\0'};
Просто хочу иметь четкие и исчерпывающие понятия о данных типах. Такие вещи не объясняются в книжках (подобным образом).

a - компилятор выделяет память для строки "hello" в статической области памяти (может даже защищённой от записи) и a указывает на неё, поэтому mes и говорил, что нужно делать const char *, чтобы в эту память никто не смог записать
b - во время выполнения программы выделяется память в куче, и b указывает на неё.
c - если определено внутри функции, то, скорее всего, компилятор выделит память в стеке и c будет указывать на неё. Кста,
char c[ 6 ] = "hello"; эквивалентно char c[] = "hello";
во втором случае компилятор сам подсчитает сколько нужно чаров

Добавлено через 3 минуты и 2 секунды
вот статья про указатели
вот ещё одна

Добавлено через 5 минут и 56 секунд
Цитата(wowka19 @  18.1.2012,  20:32 Найти цитируемый пост)

3. Очень частые warnings:warning: deprecated conversion from string constant to 'char*'

см. объяснение про статическую защищённую память.
Цитата(wowka19 @  18.1.2012,  20:32 Найти цитируемый пост)

можно ли на них забить? и как от них избавиться?

забивать нельзя ни на один warning. как избавиться - пиши const char *


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
rumit7
Дата 19.1.2012, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 16.6.2011

Репутация: нет
Всего: 7



Цитата(wowka19 @  18.1.2012,  20:32 Найти цитируемый пост)
2. Объясните в чем различия между a, b и c:
char * a = "hello";
char * b = new char[6]; b[0] = 'h', b[] = 'e', b[] = 'l', b[] = 'l', b[] = 'o', b[] = '\0';
char c[6] = {'h', 'e', 'l', 'l', 'o', '\0'};
Просто хочу иметь четкие и исчерпывающие понятия о данных типах. Такие вещи не объясняются в книжках (подобным образом).


По-моему, как раз-таки в книжках объясняется очень даже хорошо, иначе никто бы книги и не покупал.. Например, можно почитать Stephen Prata "C++ primer plus".

Конкретно вот в этой главе описаны составные типы данных С++. А вот здесь имеется ответ на некоторые Вами заданные вопросы (смотрите "Functions and C-Style Strings").
PM MAIL   Вверх
mes
Дата 19.1.2012, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(wowka19 @  19.1.2012,  06:21 Найти цитируемый пост)
А разве это не одно и тоже?

почитайте о различии массива и указателя..



--------------------
PM MAIL WWW   Вверх
wowka19
Дата 19.1.2012, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



спасибо за ссылки. почитал - понравилось.

в общем, чтоб расставить все точки...

1. Это одно и тоже:
char a[] = "hello";
char a[] = {'h', 'e', 'l', 'l', 'o', '\0'}

2. Это разные вещи:
char a[] = "hello"; // хранится в стеке, a[0] = 'H' прокатит
char * a = "hello"; // хранится в статической памяти и изменять нельзя - a[0] = 'H' не прокатит

Всё верно?

Добавлено @ 14:36
Цитата(mes @  19.1.2012,  10:40 Найти цитируемый пост)
почитайте о различии массива и указателя..

а собсно чего там сложного..
char a[] = "hello";
char * b = "hello";

a - это тоже указатель, как и b. Причем такой же char'овский

Просто различие в том на какой тип памяти указывают эти указатели - а вот это я не знаю.. и это я хочу узнать.

Это сообщение отредактировал(а) wowka19 - 19.1.2012, 16:32
PM MAIL   Вверх
rumit7
Дата 19.1.2012, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 16.6.2011

Репутация: нет
Всего: 7



Цитата(wowka19 @ 19.1.2012,  14:28)


1. Это одно и тоже:
char a[] = "hello";
char a[] = {'h', 'e', 'l', 'l', 'o', '\0'}


Да.

Цитата(wowka19 @ 19.1.2012,  14:28)

2. Это разные вещи:
char a[] = "hello"; // хранится в стеке, a[0] = 'H' прокатит


Лучше сказать, что память выделится под массив, а значит "a[0] = 'H' прокатит". Где именно? Могу сказать, что в стеке память выделяется только для локальных объектов.

Цитата(wowka19 @ 19.1.2012,  14:28)

char * a = "hello"; // хранится в статической памяти и изменять нельзя - a[0] = 'H' не прокатит


Более правильнее записать так:

Код

const char * a = "hello"


так как полюбому "a[0] = 'H' не прокатит" ввиду того, что память выделенная для "hello" не изменяемая (если она вообще выделена, т.к. компилятор может и с оптимизировать). Но не забываем, что сам "a" - указатель, и под него память выделяется, а значит его значение можно изменить:

Код

const char * a = "hello"
const char * b = "hi"

a = b;    // теперь "а" и "b" указывают на константную строку "hi". 
 

Цитата(wowka19 @ 19.1.2012,  14:28)

Всё верно?


Теперь вроде да..(?)


Цитата(wowka19 @ 19.1.2012,  14:28)

Цитата(mes @  19.1.2012,  10:40 Найти цитируемый пост)
почитайте о различии массива и указателя..

а собсно чего там сложного..
char a[] = "hello";
char * b = "hello";

a - это тоже указатель, как и b. Причем такой же char'овский

Просто различие в том на какой тип памяти указывают эти указатели - а вот это я не знаю.. и это я хочу узнать.


а - это массив размером в 6 элементов.
b - это указатель.

Это сообщение отредактировал(а) rumit7 - 19.1.2012, 16:59
PM MAIL   Вверх
xvr
Дата 20.1.2012, 12:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(wowka19 @  19.1.2012,  14:28 Найти цитируемый пост)
а собсно чего там сложного..
char a[] = "hello";
char * b = "hello";

a - это тоже указатель, как и b. Причем такой же char'овский

Ну есть небольшая разница:
Код

char* c;

a=c; // Error
b=c; // Ok
sizeof(a) == 6
sizeof(b) == 4
&a == a
&b != b


PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0609 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.