LINUX.ORG.RU

[C++] Неинтегральная константа-член класса в хедере


0

1

Хочу так:

class SomeClass 
{
   ...
   static const double A;
};
...
const double SomeClass::A = 0.01;
Это, естественно, работает, когда объявления и реализация разнесены по разным файлам. Но у меня класс шаблонный, целиком определен в хедере и поэтому при линковке генерится ошибка multiple definition of SomeClass::A, потому что хедер включается в несколько файлов. Собственно, как быть? Отдельный файл специально под это дело заводить не хочется.


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

Читай внимательней. Я не хочу заводить еще один файл, как советуют по твоей ссылке.

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

Читай внимательней. Я не хочу заводить еще один файл, как советуют по твоей ссылке.

ок, разжую, вот твой класс:

a.h

template <class T>
struct K
{
	static T x;
};
template<class T> T K<T>::x = 1;

вот два файла, которые его используют:

a.cpp

#include "a.h"
#include <cstdio>

K<int> v1;

int main()
{
	printf( "%d\n", v1.x );
}

b.cpp

#include "a.h"

K<int> v2;

собирай так:

g++ ./a.cpp ./b.cpp && ./a.out

и все работает

anonymous ()

то что вы хотите сделать можно сделать только для шаблонного класса
а вы пример привели не шаблонный
примеры можете в библиотеке Loki посмотреть

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

гм, я действительно делал для нешаблонного класса и оно не линковалось. Получается, что для нешаблонного нельзя что ли? Придется заводить отдельный файл?

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

Придется заводить отдельный файл?

да

anonymous ()
namespace {

class AAA {
public:
	AAA()
	{
	}

	void foo() const
	{
		std::cout << value << std::endl;
	}

	static const double value;
};

const double AAA::value = 3.14;

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

где темплейт, дурилка картонная?

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

тред полностью читал, анон? автор уже хочет без темплейта, судя по

гм, я действительно делал для нешаблонного класса и оно не линковалось. Получается, что для нешаблонного нельзя что ли? Придется заводить отдельный файл?

дурилка картонная... воспитатель в детсаде научил таким словишкам?

vvviperrr ★★★★★ ()

да и вообще. чем тебя

class SomeClass {
public:
	static double value() { return 3.14; }
};
не устраивает?

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

Скобочками).

Блин, я на самом деле конечно затупил и написал так, что получилось мутно, т.к. я чрезмерно упростил пример. Я случайно на это наткнулся, поэтому и удивился. У меня на самом деле так: есть шаблонный класс, который полностью определен в хедере. В этому же хедере от него с известным типом наследуется уже обычный класс, который тривиален и перегружает пару методов и добавляет эту самую константу. Ради него не хочется заводить отдельный файл, ну и хочется чтобы константа была его статическим членом. Не ахти какая проблема, просто для интереса создал тему.

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

ну безымянный неймспейс добавь, я же привел выше пример

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

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

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

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

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

Да уж. Выражение &AAA::value ведь будет иметь во всех файлах одинаковое значение, да?

Правильно ли я понимаю, что в этом случае до вызова main будет в каждом файле сгенерирован вызов конструктора типа константы (у нас double), и присваивание получившегося объекта статическому полю класса value? Т.е. сколько файлов, столько раз будет перезаписываться поле, каждый раз на одно и то же значение? Это получается некислый способ прострелить себе коленку, если константа не встроенного типа.

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

Да уж. Выражение &AAA::value ведь будет иметь во всех файлах одинаковое значение, да?

адреса у объектов в каждом cpp будут разные.

Правильно ли я понимаю, что в этом случае до вызова main будет в каждом файле сгенерирован вызов конструктора типа константы

у встроенных типов нет конструкторов

Это получается некислый способ прострелить себе коленку, если константа не встроенного типа.

ну я и говорю, что с синглтоном, к примеру, так делать не надо.

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

Мда. Лучше уж отдельный файл завести, а то потом может себе дороже выйти. Объявленный статически объект со своим адресом в каждом файле не есть хорошо. Спасибо за ответы! (зы говоря о конструкторах, я и имел в виду, конечно, невстроенные типы)

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