[zt] static 數據成員初始化

From: http://blog.csdn.net/niexiao2008/archive/2009/10/11/4635899.aspx

 

結論:

       1、類中定義的靜態數據成員必須在類定義體的外部初始化(例外:只有靜態常量整型數據成員纔可以在類中初始化)

       2、static關鍵字只能用於類定義體內部的聲明中,外部定義不能標示爲static

原因分析:

      最先分配的是全局變量,然後分配靜態變量,之後纔是類的初始化.所以,要放在全局的地方進行初始化.

例子代碼:

Triangular.h

view plaincopy to clipboardprint?
#ifndef __TRIANGULAR_H__  
#define __TRIANGULAR_H__  
 
#include <iostream>  
#include <vector>  
#include <algorithm>  
 
using namespace std;  
 
class Triangular {  
public:  
   Triangular( int len = 1, int bp = 1 );   
   Triangular( const Triangular& );  
   Triangular& operator=( const Triangular &rhs );  
 
   int length()  const { return _length;  }  
   int beg_pos() const { return _beg_pos; }  
   int elem( int pos ) const;  
 
   void length( int nlen ) { _length = nlen; }  
   void beg_pos( int npos ){ _beg_pos = npos; }  
 
   bool next( int &val ) const;  
   void next_reset() const { _next = 1; }  
 
   static bool is_elem( int );  
   static void gen_elements( int length );  
   static void gen_elems_to_value( int value );  
   static void display( int length, int beg_pos, ostream &os = cout );  
 
private:  
    int _length;    // number of elements  
    int _beg_pos; // beginning position of range  
    mutable int _next;    // next element to iterate over  
 
    enum { _max_elems = 1024 };  
    static vector<int> _elems;  
};  
 
#endif //__TRIANGULAR_H__ 
#ifndef __TRIANGULAR_H__
#define __TRIANGULAR_H__

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Triangular {
public:
   Triangular( int len = 1, int bp = 1 );
   Triangular( const Triangular& );
   Triangular& operator=( const Triangular &rhs );

   int length()  const { return _length;  }
   int beg_pos() const { return _beg_pos; }
   int elem( int pos ) const;

   void length( int nlen ) { _length = nlen; }
   void beg_pos( int npos ){ _beg_pos = npos; }

   bool next( int &val ) const;
   void next_reset() const { _next = 1; }

   static bool is_elem( int );
   static void gen_elements( int length );
   static void gen_elems_to_value( int value );
   static void display( int length, int beg_pos, ostream &os = cout );

private:
    int _length;  // number of elements
    int _beg_pos; // beginning position of range
    mutable int _next;    // next element to iterate over

    enum { _max_elems = 1024 };
    static vector<int> _elems;
};

#endif //__TRIANGULAR_H__

 

Triangular.cpp

view plaincopy to clipboardprint?
#include "Triangular.h"  
#pragma warning(disable: 4018)  
Triangular::Triangular( int len, int beg_pos )  
    : _length( len > 0 ? len : 1 ),  
      _beg_pos( beg_pos > 0 ? beg_pos : 1 )  
{  
    _next = _beg_pos;  
 
    int elem_cnt = _beg_pos + _length;  
    if ( _elems.size() < elem_cnt )  
         gen_elements( elem_cnt );  
}  
 
Triangular::Triangular( const Triangular &rhs )  
    : _length ( rhs._length  ),  
      _beg_pos( rhs._beg_pos ),       
      _next( rhs._next )  
{}   
 
int Triangular::  
elem( int pos ) const 
    { return _elems[ pos-1 ]; }  
 
bool Triangular::  
next( int &value ) const 
{  
    if ( ! _next )   
        return false;  
 
    if ( _next < _beg_pos + _length ) {    
        // error: modifying _next  
          value = _elems[ _next++ ];  
        return true;  
    }  
    _next = 0; // error: modifying _next  
    return false;  
}  
 
Triangular&  
Triangular::  
operator=( const Triangular &rhs )  
{  
    if ( this != &rhs ) {   
        _length = rhs._length;  
        _beg_pos = rhs._beg_pos;  
        _next = 1;  
    }  
 
   return *this;  
};  
 
bool Triangular::  
is_elem( int value )  
{  
   if ( ! _elems.size() || _elems[ _elems.size()-1 ] < value )  
        gen_elems_to_value( value );  
 
   vector<int>::iterator found_it;   
   vector<int>::iterator end_it = _elems.end();  
 
   found_it = find( _elems.begin(), end_it, value );  
   return found_it != end_it;  
}  
 
void Triangular::  
gen_elements( int length )  
{  
    if ( length < 0 || length > _max_elems ){  
        cerr << "Triangular Sequence: oops: invalid size: " 
             << length << " -- max size is " 
             << _max_elems << endl;  
        return;  
    }  
     
    if ( _elems.size() < length )  
    {  
        int ix = _elems.size() ? _elems.size()+1 : 1;  
        for ( ; ix <= length; ++ix )  
              _elems.push_back( ix*(ix+1)/2 );  
    }  
}  
 
void Triangular::  
gen_elems_to_value( int value )  
{    
   int ix = _elems.size();  
   if ( !ix ){  
       _elems.push_back( 1 );  
       ix = 1;  
   }  
 
   while ( _elems[ ix-1 ] < value && ix < _max_elems )  
   {  
//     cout << "elems to value: " << ix*(ix+1)/2 << endl;  
       _elems.push_back( ix*(ix+1)/2 );  
       ++ix;  
   }  
 
   if ( ix == _max_elems )  
        cerr << "Triangular Sequence: oops: value too large " 
             << value << " --  exceeds max size of " 
             << _max_elems << endl;  
   
}  
 
void Triangular::  
display( int length, int beg_pos, ostream &os )  
{  
    if ( length <= 0 || beg_pos <= 0 ){  
         cerr << "invalid parameters -- unable to fulfill request: " 
              << length << ", " << beg_pos << endl;  
         return;  
    }  
 
    int elems = beg_pos + length - 1;  
 
    if ( _elems.size() < elems )  
         gen_elements( elems );  
 
    for ( int ix = beg_pos-1; ix < elems; ++ix )  
          os << _elems[ ix ] << ' ';  
}  
 
//static數據成員必須在類定義體的外部定義(正好一次)  
//static關鍵字只能用於類定義體內部的聲明中,定義不能標示爲static 參考:《C++ Primer中文第四版》 P401  
//原因分析:最先分配全局變量..然後分配靜態變量..這些在類的初始化之前.所以,要放在全局的地方初始化.     
 
vector<int> Triangular::_elems;  //問題所在 
#include "Triangular.h"
#pragma warning(disable: 4018)
Triangular::Triangular( int len, int beg_pos )
    : _length( len > 0 ? len : 1 ),
      _beg_pos( beg_pos > 0 ? beg_pos : 1 )
{
 _next = _beg_pos;

 int elem_cnt = _beg_pos + _length;
    if ( _elems.size() < elem_cnt )
         gen_elements( elem_cnt );
}

Triangular::Triangular( const Triangular &rhs )
 : _length ( rhs._length  ),
      _beg_pos( rhs._beg_pos ),  
   _next( rhs._next )
{}

int Triangular::
elem( int pos ) const
    { return _elems[ pos-1 ]; }

bool Triangular::
next( int &value ) const
{
 if ( ! _next )
        return false;

 if ( _next < _beg_pos + _length ) { 
        // error: modifying _next
    value = _elems[ _next++ ];
        return true;
 }
 _next = 0; // error: modifying _next
 return false;
}

Triangular&
Triangular::
operator=( const Triangular &rhs )
{
 if ( this != &rhs ) {
     _length = rhs._length;
  _beg_pos = rhs._beg_pos;
  _next = 1;
 }

   return *this;
};

bool Triangular::
is_elem( int value )
{
   if ( ! _elems.size() || _elems[ _elems.size()-1 ] < value )
        gen_elems_to_value( value );

   vector<int>::iterator found_it;
   vector<int>::iterator end_it = _elems.end();

   found_it = find( _elems.begin(), end_it, value );
   return found_it != end_it;
}

void Triangular::
gen_elements( int length )
{
    if ( length < 0 || length > _max_elems ){
        cerr << "Triangular Sequence: oops: invalid size: "
             << length << " -- max size is "
             << _max_elems << endl;
        return;
 }
  
    if ( _elems.size() < length )
 {
  int ix = _elems.size() ? _elems.size()+1 : 1;
  for ( ; ix <= length; ++ix )
     _elems.push_back( ix*(ix+1)/2 );
 }
}

void Triangular::
gen_elems_to_value( int value )

   int ix = _elems.size();
   if ( !ix ){
    _elems.push_back( 1 );
    ix = 1;
   }

   while ( _elems[ ix-1 ] < value && ix < _max_elems )
   {
//     cout << "elems to value: " << ix*(ix+1)/2 << endl;
    _elems.push_back( ix*(ix+1)/2 );
    ++ix;
   }

   if ( ix == _max_elems )
     cerr << "Triangular Sequence: oops: value too large "
             << value << " --  exceeds max size of "
             << _max_elems << endl;
 
}

void Triangular::
display( int length, int beg_pos, ostream &os )
{
 if ( length <= 0 || beg_pos <= 0 ){
   cerr << "invalid parameters -- unable to fulfill request: "
     << length << ", " << beg_pos << endl;
   return;
 }

 int elems = beg_pos + length - 1;

 if ( _elems.size() < elems )
   gen_elements( elems );

 for ( int ix = beg_pos-1; ix < elems; ++ix )
    os << _elems[ ix ] << ' ';
}

//static數據成員必須在類定義體的外部定義(正好一次)
//static關鍵字只能用於類定義體內部的聲明中,定義不能標示爲static 參考:《C++ Primer中文第四版》 P401
//原因分析:最先分配全局變量..然後分配靜態變量..這些在類的初始化之前.所以,要放在全局的地方初始化.  

vector<int> Triangular::_elems;  //問題所在

測試代碼:

TestTriangular.cpp

view plaincopy to clipboardprint?
//Trianglar測試代碼  
#include "Triangular.h"  
 
ostream&  
operator<<( ostream &os, const Triangular &rhs )  
{  
    os << "( " 
        << rhs.beg_pos() << " , " 
        << rhs.length()  << " ) ";  
 
    rhs.display( rhs.length(), rhs.beg_pos(), os );  
    return os;  
}  
 
istream&  
operator>>( istream &is, Triangular &rhs )  
{  
    Triangular tri(4);  
    cout << tri << " - sum of elements: "<< sum(tri) << endl;  
 
    Triangular tri2(4, 3);  
    cout << tri2 << "- sum of elements: " << sum(tri2) << endl;  
 
    Triangular tri3(4, 8);  
    cout << tri3 << " - sum of elements: " << sum(tri3) <<endl;  
        char ch1, ch2;  
    int bp, len;  
 
    is >> ch1 >> bp >> ch2 >> len;  
 
   rhs.beg_pos( bp );   
   rhs.length( len );   
   rhs.next_reset();  
 
    return is;  
}  
 
int main()  
{  
      
 
    char ch;  
    bool more = true;  
 
    while (more)  
    {  
        cout << "Enter value: ";  
        int ival;  
        cin >> ival;  
 
        bool is_elem = Triangular::is_elem(ival);  
        cout << ival << (is_elem ? " is " : " is not ") << "an element in the Triangular series./n" << "Another value?(y/n)";  
 
        cin >> ch;  
        if(ch == 'n' || ch == 'N')  
            more = false;  
    }  

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/niexiao2008/archive/2009/10/11/4635899.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章