2013-07-11 4 views
0

Есть ли все же, чтобы скрыть определение класса C++ для единиц компиляции?Есть ли способ скрыть определение класса C++ в блоке компиляции?

Рассмотрим,

//test1.cpp 
struct local 
{ 
    local() 
    { 
     std::cout<<"test1::local\n"; 
    } 
}; 
void test1() 
{ 
    local l; 
} 


//test2.cpp 
struct local 
{ 
    local() 
    { 
     std::cout<<"test2::local\n"; 
    } 
}; 

void test2() 
{ 
    local l; 
} 



//main.cpp 
void test1(); 
void test2(); 
int main() 
{ 
    test1(); 
    test2(); 
} 

он должен связать & печать, как показано ниже,

test1::local 
test2::local 

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

+3

Конечно: дайте своим классам разные имена. Здесь код нарушает правило определения (ODR), поскольку он определяет ** то же ** имя двумя разными способами. Это приводит к неопределенному поведению. –

+12

Анонимные пространства имен * точно * то, что вам нужно, и информация о символах - это деталь реализации, о которой вам не о чем беспокоиться. – slaphappy

ответ

0

Ваш код нарушает одно правило определения здесь, потому что у вас есть два класса с одинаковой областью и именем, но с разными определениями. Поэтому все ставки отключены, а it should link & print like below, является полностью ложным утверждением, потому что ваш код имеет неопределенное поведение.

Однако в этом случае, я думаю, что функция локального типа может быть именно то, что вы хотите, например:

//test1.cpp 
void test1() 
{ 
    struct local 
    { 
     local() 
     { 
      std::cout<<"test1::local\n"; 
     } 
    }; 

    local l; 
} 

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

7

Вы можете использовать анонимные имена:

namespace { 
    struct local 
    { 
     local() 
     { 
      std::cout<<"test1::local\n"; 
     } 
    }; 
} 

void test1() 
{ 
    local l; 
} 

Это эффективно ограничивает сферу имени local к единице перевода, где она используется. (Формально это неправильно, но если вы думаете об этом так, вы не ошибетесь)

+2

@chris - крики, я не заметил этого (фиктивного) требования. –

+4

Ага, я почти не мог вспомнить ни одного имени, чтобы найти его, но http://blogs.msdn.com/b/oldnewthing/archive/2013/02/06/10391383.aspx – chris

+0

Педант: они называются неназванный, не анонимный. –

Смежные вопросы