статический массив символов, ведущий себя неожиданно в разных классах - PullRequest
1 голос
/ 14 апреля 2011

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

У меня есть простой заголовочный файл, назовите его a.h

, который имеет нижеследующее и ничего более (он действует как файл глобальных настроек для всех файлов в моем проекте, которые решили включить его)

#ifndef A_H
#define A_H
namespace settings{
   static char name[16]={'\0'};
}
#endif

Затем у меня есть другой класс с собственным заголовочным файлом, назовем его b.cpp (с b.h не показан)

#include "a.h"

void B::doSomething()
{
    strcpy(settings::name,"I like Dogs");
}

Наконец, третий класс, который обращается к 'settings :: name, назовите его c.cpp (с c.h не показан)

#include "a.h"

void C::printSomething()
{
    printf("Some Girls Say %s\n",settings::name);
}

Увы, все, что печатается, это "Some Girls Say". Что дает? Я не понимаю, как settings :: name не выживает уничтожение функции B :: doSomething () (я могу только догадываться, что это проблема). Является ли strcpy ленивым и просто указывает на настройки :: имя, с которого начинается «I Like Dogs», а не действует как strdup?

Любая помощь и обходной путь высоко ценится. Спасибо!

РЕДАКТИРОВАТЬ: Для большей ясности B.doSomething () вызывается перед C.printSomething ().

Ответы [ 3 ]

7 голосов
/ 15 апреля 2011

ключевое слово static связывает name с каждой единицей перевода, в которую он включен, поэтому каждый файл .cpp в основном имеет свою собственную версию name.

То, что вы хотите сделать, это поместитьname, которым вы хотите поделиться в одном файле .cpp (без static и объявить его с помощью extern в файле .h.

, так что это:

a.cpp

namespace settings {
    char name[16] = { 0 };
}

ах

namespace settings {
    extern char name[16];
}

b.cpp

void B::doSomething()
{
    strcpy(settings::name,"I like Dogs");
}

c.cpp

#include "a.h"

void C::printSomething()
{
    printf("Some Girls Say %s\n",settings::name);
}
1 голос
/ 15 апреля 2011

Включив этот заголовок в два исходных файла, вы получите два отдельных хранилища. Включение заголовка немного похоже на вставку этого кода в исходные файлы. Таким образом, у каждого из них есть своя статическая переменная с именем name.

Чтобы заставить это делать то, что вы хотите, вам нужно:

  • Используйте extern, а не static, в заголовке. Это фактически означает, что каждый файл, включая заголовок, будет ссылаться на внешнюю переменную.
  • Определите переменную в одном из ваших исходных файлов. Это нужно определить где-то, один раз. Не используйте static или extern при его определении.
0 голосов
/ 15 апреля 2011

Прежде всего напишите в a.cpp

namespace settings{
   char name[16];
}

, затем убедитесь,

B::doSomething()

называется.

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