2015-11-01 5 views
0

http://ideone.com/1ohrsOРеализация статического конструктора в C++ не работает

push_back называется внутри конструктора static_constructor, не отражается. Зачем?

#include <iostream> 
#include <vector> 
#include<memory> 
#include<string> 

using namespace std; 

class has_static_constructor 
{ 
    public: 
    friend class static_constructor; 
    static vector<int> v; 



     class static_constructor 
     { 
      public: 

      vector<int> * upt; //&v; 
      static_constructor() 
      { 
       cout<<"inside static_constructor"; 
       upt = &has_static_constructor::v; 
       has_static_constructor::v.push_back(1); 
       has_static_constructor::v.push_back(20); 
      } 

     } ; 

     static std::unique_ptr<has_static_constructor::static_constructor> upt ; 
}; 



unique_ptr<has_static_constructor::static_constructor> has_static_constructor::upt(new has_static_constructor::static_constructor()); 

vector<int> has_static_constructor::v(2,100); 

int main() { 
    // your code goes here 

    for (std::vector<int>::const_iterator i = has_static_constructor::v.begin(); i != has_static_constructor::v.end(); ++i) 
    { std::cout << *i << ' '; 
     cout<<"\n I was here\n"; 
    } 

    return 0; 
} 

Выход:

inside static_constructor100 
I was here 
100 
I was here 
+0

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

+1

Лучше размещать код в своем сообщении, а не ссылаться на код на другом сайте, который может исчезнуть. В любом случае конструктор вашего класса 'static_constructor' обращается к статическому члену' has_static_constructor' до того, как этот элемент будет создан. Результатом этого является неопределенное поведение в соответствии со стандартом C++. Это означает, что любое поведение приемлемо, включая то, что вы видите. – Peter

+0

@Peter 'upt = & has_static_constructor :: v;' inside 'static_constructor()', должен инициализировать 'v', перед вызовом' push_back() '. Я что-то упускаю? – q126y

ответ

3

static_constructor() вызывается до has_static_constructor::v инициализации.

Move

unique_ptr<has_static_constructor::static_constructor> has_static_constructor::upt(new has_static_constructor::static_constructor()); 

после

vector<int> has_static_constructor::v(2,100); 

, что ожидаемое поведение.

Но лучше избегайте этих глобальных целей.

+0

ваше предложение работает, , но 'upt = & has_static_constructor :: v;' inside 'static_constructor()', должен инициализировать 'v', перед вызовом' push_back() ', поэтому мой исходный код тоже должен работать. Я что-то упускаю? – q126y

+0

@ q126y Почему вы ожидаете назначения 'upt' для инициализации' v'? –

+0

@KonradRudolph На самом деле я пытался осуществить то, что вы сказали в комментариях здесь http://stackoverflow.com/questions/5803953/static-constructor-in-c > @Tod Очень действительный комментарий. К сожалению, с ленивой загрузкой довольно сложным является бит .По сути, я решил бы его со статическим > unique_ptr для вложенного класса, который содержит все «статические» элементы как, > на самом деле, нестатические члены и который инициализируется 0 и возвращает > действительному указателю один раз это первый доступ. Я думал, что доступ к 'v', заставит программу искать его и инициализировать. – q126y

0

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

#include <iostream> 
#include <vector> 


class has_static_constructor 
{ 
    // note - all private 

    struct static_data { 
     static_data() 
     : _v(2, 100) 
     { 
      _v.push_back(1); 
      _v.push_back(20); 
     } 
     std::vector<int> _v; 
    }; 

    static static_data& statics() { 
     static static_data sd; 
     return sd; 
    } 

    // public interface 
public: 

    static std::vector<int>& v() { return statics()._v; } 

}; 

auto main() -> int 
{ 
    for (const auto& i : has_static_constructor::v()) 
    { 
     std::cout << i << std::endl; 
    } 
    return 0; 
} 

ожидается выход:

100 
100 
1 
20 

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

  • Нет связанных вопросов^_^