Можете ли вы остановить создание неиспользуемых объектов c? - PullRequest
0 голосов
/ 18 февраля 2020

Когда я связываю файл, содержащий статический c объект, конструктор этого объекта запускается независимо от того, используется ли объект когда-либо или даже включен заголовок. Есть ли способ в g ++, чтобы остановить это поведение, или единственный ответ просто не связывать файл?

foo.h

#include <iostream>

class Bar {
public:
    Bar(int inMemberInt) {
        std::cout << "In Bar constructor." << std::endl;
    }
};

class Foo {
public:
    static const Bar constVar;
};

foo. cpp

#include "foo.h"

const Bar Foo::constVar(1);

main. cpp

#include <iostream>

int main() {
    std::cout << "Hello." << std::endl; 

    return 1;
}

Команда построения

g++ foo.h foo.cpp main.cpp -o main

Выход

In Bar constructor.
Hello.

Ответы [ 2 ]

5 голосов
/ 18 февраля 2020

Вы можете сделать класс шаблоном (возможно, с параметром шаблона по умолчанию), и тогда определение элемента данных stati c будет реализовано только тогда, когда (odr-) используется где-то в программе.

Это требует Вы должны переместить определение членов класса в заголовок. Если это слишком большое влияние, вы можете рассмотреть возможность помещения члена stati c в базовый класс, который является шаблоном класса, который будет иметь тот же эффект, что и весь класс в качестве шаблона, пока вы не t ссылка на элемент * stati c где угодно. В любом случае определение элемента stati c необходимо будет переместить в заголовок (явное создание экземпляра будет противодействовать ожидаемому эффекту.)

Это не значит, что если элемент stati c используется (odr-), инициализатор будет запускаться только при первом использовании переменной при запуске программы. Является ли это так или нет, зависит от реализации.


Альтернатива, которая гарантирует не только то, что инициализатор никогда не запускается, когда переменная не используется в программном коде, но и гарантирует, что он запускается именно при первом использовании, - чтобы использовать локальную переменную static в функции-члене static:

static const Bar& constVar() {
    static const Bar instance(1);
    return instance;
};

Затем используйте ее как constVar() вместо constVar. (Определение функции также может быть вне класса.) Однако это может привести к снижению производительности, поскольку реализация локальной статики должна быть поточно-ориентированной.

1 голос
/ 18 февраля 2020

Другим вариантом является определение объекта c в его собственном исходном файле. Затем скомпилируйте этот исходный файл в объектный файл и свяжите его с библиотекой stati c (.a) вместе с другими объектными файлами (если есть). При связывании вашего исполняемого файла (или совместно используемой библиотеки) с библиотекой stati c компоновщик включает только те файлы .o из библиотеки stati c, которые разрешают любой из неразрешенных символов. Таким образом, если ничто не ссылается на этот объект * stati c, объектный файл, в котором он определен, не связан с вашей исполняемой или общей библиотекой.

...