Задать вопрос
Julila
@Julila
вечный студент / german version

Почему появляется ошибка компилятора '?

Добрый день. Компиляция проходит нормально, но при линковке появляется ошибка

/tmp/cc0qoW0L.o: In function `main':
/tmp/cc4Zebx3.o: In function `Skript::Skript(std::basic_string, std::allocator >)':
A2.cpp:(.text._ZN16SkriptC2ESs[_ZN16SkriptC5ESs]+0x36): undefined reference to `Skript::counter'


class Skript {
	
public:
	static int counter; 
  Skript (string v) : text(v) { 
	  counter++;
	  }
  ~Skript() {
	  	  counter--; }


class RSA : public  Skript{
public:


  RSA() : Skript("RSA"){ };
  ~RSA() { 	  };

int main() 
{      
Skript *v1 = new RSA();  // Error
 //   int c1 = Skript::counter;
 

//delete v1;
  • Вопрос задан
  • 163 просмотра
Подписаться 1 Оценить Комментировать
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Пригласить эксперта
Ответы на вопрос 1
@Mercury13
Программист на «си с крестами» и не только
Ошибся тут не компилятор, а линкер. Этот вопрос идёт со времён Си и происходит из технологии компиляции: несколько единиц компиляции компилируются независимо, а потом собираются воедино компоновщиком (линкером).

Статический член класса — это глобальная переменная, и если объявлять её в каждой единице компиляции, то какую потом линкеру брать? Вот мы и пришли к выводу: static int counter; в хедере — это тот же extern. Другими словами, мы не объявляем переменную, а говорим: не беспокойся, компилятор, в какой-то единице компиляции она будет.

И решается этот вопрос так же, как для любого extern’а: в одной единице компиляции (CPP) объявляем
int Skript::counter;
Можно также статически инициализировать этот счётчик:
int Skript::counter = 0;

Ах да. А технология эта с единицами компиляции откуда? Из ассемблера. Если программа у нас почти на всю память в 16 килобайт, то ассемблерный текст намного, намного превышает память ПК. Вот и приходится ассемблировать по частям, а потом собирать куски полуготового машинного кода в полную программу. Наконец, чтобы язык заработал, КиР пришлось написать только компилятор Си, а линкер — имеющийся.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы