LINUX.ORG.RU

Запутался с C++ + static

 ,


0

1

Добрый день. Есть такой кусочек кода:

class A {
    public:
    static int i;
};

class B {
    public:
    void setVal(int j);
};

void B::setVal(int j) {
    A::i = j;
}

int main() {
    B _b;
    _b.setVal(3);
    return 0;
}

Вылетает с ошибкой:

g++ -o test_static test_static.cpp 
/tmp/ccnlzHDY.o: In function `B::setVal(int)':
test_static.cpp:(.text+0x7): undefined reference to `A::i'
collect2: ld returned 1 exit status

Подскажите, в чём ошибка плз.

Подскажите, в чём ошибка плз.

в днк.

начнём с того, что это моветон

public:
    static int i;

ну и как бэ «undefined reference to `A::i'»...

erfea ★★★★★ ()

Все переменные должны где-то жить в памяти. В заголовочных файлах, как известно, память выделять не принято. При объявлении класса она тоже не выделяется. Поэтому в одном из файлов с реализацией нужно написать int A::i, как уже здесь сказали.

note173 ★★★★★ ()
Ответ на: комментарий от erfea

Если таки сильно хочется делают обычно дружбу

А вот это - моветон.

А прямой доступ к полям класса разрешён для POD-структур, например.

schizoid ★★★ ()
Ответ на: комментарий от schizoid

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

erfea ★★★★★ ()
Ответ на: комментарий от GreenBag

а особенно note173

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

erfea ★★★★★ ()
Ответ на: комментарий от erfea

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

А если таки нет? И что ты ему сделаешь, о повелитель интернетов?

no-such-file ★★★★★ ()
Ответ на: комментарий от no-such-file

Ничего, мне остается только надеяться, особенно если он будет свой код в массы выкладывать и мне придётся его парсить. Массовое отсутсвие понимания ЯП - бич современных программистов (((

erfea ★★★★★ ()

посмотри любую книгу С++ там написано как нужно вести себя

Boy_from_Jungle ★★★★ ()
Ответ на: комментарий от erfea

Если поле класса предусматривает чтение и запись значения извне и не реализует при этих операциях никакой другой логики, то не вижу причины делать это поле закрытым и писать к нему геттеры/сеттеры.

А дружба как альтернатива - не есть хорошо.

theNamelessOne ★★★★★ ()
Ответ на: комментарий от theNamelessOne

Да вообще в гетерах/сетерах мало логики, если только там нет доп. логики, изменение переменной только при опр. условиях, ну или синхронизация потоков. В любом случае такой код имхо вообще глупый, бессмысленный и беспощадный:

int A::getI()
{
    return i;
}

void A::setI(int newI)
{
    i = newI;
}

ООП ради ООП прямо какое-то.

Dudraug ★★★★★ ()
Ответ на: комментарий от Dudraug

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

именно это я и имел в виду, когда говорил про «другую логику»

theNamelessOne ★★★★★ ()
Ответ на: комментарий от theNamelessOne

При таком раскладе я не вижу вообще необходимости использовать класс. Инкапсуляцию придумывали таки не что бы класс использовали вместо структуры.

erfea ★★★★★ ()
Ответ на: комментарий от erfea

Не надо впадать в крайности. Помимо публичных полей тот же класс может содержать и закрытые поля, которые уже выставлять на обозрение пользователю нельзя, т.к. неправильное их использование/изменение уже может что-то сломать. Для таких полей и нужно писать геттеры/сеттеры, которые будут производить необходимые действия по обработке полей при выдаче/установке значений.

theNamelessOne ★★★★★ ()
Ответ на: комментарий от erfea

Просто на мой взгляд инкапсуляция - это не сокрытие переменных класса, или его стрктурной части. Да и вообще даже не сокрытие, на мой взгляд инкапсуляция - это разделение реализации и интерфейса. Даже так. А что есть интерфейс, а что реализация решает какждый программист сам.

Dudraug ★★★★★ ()
Ответ на: комментарий от erfea

стараюсь избегать .... дружбы

А как же «не имей сто рублей, а имей сто друзей»?

anonymous ()
Ответ на: комментарий от Dudraug

Инкапсуляции вообще понятие не ООПшное

Основные признаки ООП: инкапсуляция, полиморфизм, наследование.

erfea ★★★★★ ()
Ответ на: комментарий от theNamelessOne

Офигенно потом выглядит

class.setX(5);
class.Y=4;
class::Z=6;
Здесь уже как минимум приходим к некрасивостям в коде. А далее давайте вспомним, что если таки нам вдруг потом понадобится делать с полем что-то внутри класса (ПО обычно ещё и сопровождать приходится после того как его написал, даже если другим лицам), то придётся отлавливать потом в коде ВСЕ обращения напрямую к полю. А я дурак, конечно, зачем-то думаю наперёд... ну-ну...

erfea ★★★★★ ()
Ответ на: комментарий от erfea

Офигенно потом выглядит

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

А далее давайте вспомним, что если таки нам вдруг потом понадобится делать [...skipped...]

вот тут я не распарсил. Поясни

theNamelessOne ★★★★★ ()
Ответ на: комментарий от theNamelessOne

а мне кажется...

Когда кажется, крестятся

не распарсил...

Имеем два класса:

class a {
public:
    int x;
}

class b {
pubic:
   int getX();
   setX(const int &newX);
private:
   int x;
}
Где в в разных местах имеем:
a.x=value;
b.setX(value);
В один прекрасный момент, ВНЕЗАПНО, нам понадобилось реализовать какую-то логику для поля «int x», или другими словами потребовалась инкапсуляция. Что мы делаем: 1 для класса b переписываем геттер и сеттер, спим спокойно; 2 для класса a переписываем геттер и сеттер, лезем лузгать свой говнокод на предмет «a.x=value;». Итого: прямое обращение к полям - быдлокод. Так понятно?

erfea ★★★★★ ()
Ответ на: комментарий от erfea

Основные признаки ООП: инкапсуляция, полиморфизм, наследование.

То что это признаки не означает что это ООП-понятие. Завязывай цитаты из лекций читать, а начинай думать. Понятие инкапсуляции не относится к ООП напрямую, оно используется в ООП, но не является понятием введенном в ООП, или используемом только там.

Dudraug ★★★★★ ()
Ответ на: комментарий от erfea

Очень часто (по опыту примерно в 90%) изменение сетера и гетера (логики) требуют еще изменения списка параметров, а значит лопатить код все равно придется. Структурный подход конечно имеет недостатки, в том числе и эти, но приемущества он тоже имеет.

Dudraug ★★★★★ ()

Ну и скажите мне противники ООП как мне сделать аналог Q_PROPERTY без геттеров и сеттеров? Напоминаю, что свойство должно уметь уведомлять подписчиков о том, что оно изменилось!

Gorthauer ★★★★★ ()
Ответ на: комментарий от Gorthauer

Тут нет противников ООП, просто ООП куда шире и тоньше понятие. Еще раз. Поле (переменная член) может быть ИНТЕРФЕЙСОМ класса, а значит ей НЕ МОЖЕТ потребоваться дополнительная логика. Интерфейс не изменен. Когда интерфейс меняется, то это уже другая песня.

Dudraug ★★★★★ ()
Ответ на: комментарий от Dudraug

То что это признаки не означает что это ООП-понятие. Завязывай цитаты из лекций читать, а начинай думать. Понятие инкапсуляции не относится к ООП напрямую, оно используется в ООП, но не является понятием введенном в ООП, или используемом только там.

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

Очень часто (по опыту примерно в 90%) изменение сетера и гетера (логики) требуют еще изменения списка параметров, а значит лопатить код все равно придется.

Хорошо придумал.... но не убедительно. Хоть сабж и правда (кроме 90%), не вижу это поводом превращать обозначеную мной жлементарную операцию в переписывание всей программы.

Структурный подход конечно имеет недостатки, в том числе и эти, но приемущества он тоже имеет.

Расскажи мне об этих преимуществах.

erfea ★★★★★ ()
Ответ на: комментарий от erfea

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

Я где-то сказал, что бывает ООП без инкапсуляции? Читать научись.

Dudraug ★★★★★ ()
Ответ на: комментарий от Dudraug

При правильном проектировании, тебе не придётся переделывать интерфейсы или будешь это делать по минимуму. Если из-за лени наваять пару строчек писать такой говнокод, то программа в момент превратится в свалку, минимальная правка которой превращается в секс.

erfea ★★★★★ ()
Ответ на: комментарий от erfea

Расскажи мне об этих преимуществах.

О приемуществах структур над классами? Так это тебе на первый курс универа надо.

Dudraug ★★★★★ ()
Ответ на: комментарий от Dudraug

Т.е. сказать тебе нечего... ЗЫ мы говорили об использовании классов в качестве структур, причём частичном. А не сравнивали структуры vs классы.

erfea ★★★★★ ()
Ответ на: комментарий от erfea

О том, что понятие инкапсуляции шире чем приват/паблик, обернуть все сетерерами/гетерами. В первую очередь - это разделение интерфейса и реализации, все остальное уже неважно, либо зависит от языка, либо от твоей головы на плечах или еще от других факторов. Я к тому, что «нельзя делать переменную без сетеров и гетеров» - это ненужный шаблон. ДА, согласен, возможно в 90% случаев это полезно и действительно так. Но я к тому, что не стоит себя ограничивать шаблонами. Я считаю, что подобный стереотип что-то вроде «ни в коем случае нельзя использовать goto!!!»

Dudraug ★★★★★ ()
Ответ на: комментарий от erfea

Мы говорили, о том, что интерфейс не обязательно методы. Просто возможно в твоих, моих, ОП проектах это так и нужно делать. Но если вдруг возникнет необходимость, то боятся делать переменные открытыми не стоит, лишь из-за того что «это плохой стиль».

Dudraug ★★★★★ ()
Ответ на: комментарий от erfea

Когда кажется, крестятся

Ты к чему это сказал? Аргументы кончились?

В один прекрасный момент, ВНЕЗАПНО, нам понадобилось реализовать какую-то логику для поля «int x», или другими словами потребовалась инкапсуляция

Такие вопросы возникают на раннем этапе проектирования, так что незачет

theNamelessOne ★★★★★ ()
Ответ на: комментарий от theNamelessOne

Такие вопросы возникают на раннем этапе проектирования, так что незачет

Ну в его словах есть доля правды все же.Проект это не статичная сущность. Как правило у проекта есть развитие. Версия 1.1, 2.0, 100.500...

Dudraug ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.