コピーコンストラクタが呼ばれる回数

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
大工

コピーコンストラクタが呼ばれる回数

#1

投稿記事 by 大工 » 16年前

ダイクストラ法を実行するプログラムを作っています.(まだ骨組みですが^^;

fromWhatクラスを要素にもつvectorの初期化をinit_path関数で行っています.
具体的な内容は

char from_ -> どのノードから来たのか 初期値は '-'
int what_ -> ここまでにどれくらいコストがかかったのか 初期値は UNDEF(= -1)

です.

久しぶりにC++を触るのでコピーコンストラクタが動いてるのかな?と確認したとろこ

実行結果:
before
0x804c008call
hoge
0x804c018call
0x804c020call
hoge
0x804c030call
0x804c038call
0x804c040call
hoge
after

が得られました.

いま,sizeを3としているのですがコピーコンストラクタが僕の予想では3回だったのに
予想を上回る回数が呼び出されています.(グラフのサイズが大きくなるとこの回数は無視できない気がします.

なぜこの様な事態が起こってしまうのでしょうか?

理想的な形としてはpush_backする度にコピーコンストラクタが1度呼ばれる -> この繰り返し

です.これは可能でしょうか?
#include<iostream>
#include<vector>
#include<map>
#include<list>

// MACROS
#define UNDEF -1

// STRUCT
class fromWhat {

public:
  fromWhat(char _from, int _what);
  fromWhat(const fromWhat& obj);
  void from(char _from);
  void what(int  _what); 
  char fromShow() {return from_;}
  int  whatShow() {return what_;}

private:
  char from_;
  int  what_;
};

fromWhat::fromWhat(char _from, int _what) {

  from_ = _from;
  what_ = _what;
}
fromWhat::fromWhat(const fromWhat& obj) {

  std::cout << this;
  std::cout << "call" << std::endl;
}
void fromWhat::from(char _from) {

  from_ = _from; 
 
  return;
}
void fromWhat::what(int _what) {

  what_ = _what; 
 
  return;
}

// PROTOTYPE DCLARE
void init_path(std::vector<fromWhat>*, int);
void init_adj(std::vector<std::list<char> >*, int);

int main(void) {

//source -> source node
//
//size   -> the number of node
//
//path   -> store path infomation
// ex:
// path[1]: 1 is node id
// char   : from node id
// cost   : how cost from source to here
//
//adj    -> show adjacency list eace node

  int source_;
  int size_;
  std::vector<fromWhat> path_;
  std::vector<std::vector<char> > adj_;

  size_ = 3;

  std::cout << "before" << std::endl;
  init_path(&path_, size_);
  std::cout << "after" << std::endl;

//  for(int i = 0; i < size_; i++) {
//
//    std::cout << "one node" << std::endl;
//   
//    std::cout << path_.fromShow() << std::endl;
//    std::cout << path_.whatShow() << std::endl;
//  }

  // adjacency list
//  std::vector<char> degree;
//  
//  for(int i = 0; i < 3; i++) {
//
//    degree.push_back('a' + i);
//  }
//
//  for(int i = 0; i < 3; i++) {
//
//    std::cout << degree << std::endl;
//  }

//  adj_.push_back(degree);
//
//  degree.push_back('k');
//
//  adj_.push_back(degree);
//
//  std::cout << adj_.size() << std::endl;
//
//  for(int i = 0; i < adj_.size(); i++) {
//
//    std::vector<char>::iterator it = adj_.begin(); 
//    
//    while(it != adj_.end()) {
//
//      std::cout << i << ": ";
//      std::cout << (*it) << std::endl;
//      it++;
//    }
//  }
//
//  adj_.pop_back();
//
//  std::cout << adj_.size() << std::endl;
//
//  for(int i = 0; i < adj_.size(); i++) {
//
//    std::vector<char>::iterator it = adj_.begin(); 
//    
//    while(it != adj_.end()) {
//
//      std::cout << i << ": ";
//      std::cout << (*it) << std::endl;
//      it++;
//    }
//  }
  return 0;
}

void init_path(std::vector<fromWhat>* _path, int _size) {

  for(int i = 0; i < _size; i++) {

    _path->push_back(fromWhat('-', UNDEF));
    std::cout << "hoge" << std::endl;
  }

  return;
}

たかぎ

Re:コピーコンストラクタが呼ばれる回数

#2

投稿記事 by たかぎ » 16年前

> なぜこの様な事態が起こってしまうのでしょうか?

vectorが内部で管理しているメモリ領域を拡張するたびに、元の領域から新しい領域にコピーする必要があるためです。
多くの実装では、メモリ領域のサイズが倍、倍に拡張されますので...

before
0x804c008call ← push_back
hoge
0x804c018call ← メモリ領域拡張(1個コピー)
0x804c020call ← push_back
hoge
0x804c030call ← メモリ領域拡張(1個コピー)
0x804c038call ← もう1個コピー
0x804c040call ← push_back
hoge
after

ということかと思います。

> 理想的な形としてはpush_backする度にコピーコンストラクタが1度呼ばれる -> この繰り返し

これを実現したいのであれば、事前にreserveしておく必要があります。
あるいは、vectorではなくlist等を使ってください。

大工

Re:コピーコンストラクタが呼ばれる回数

#3

投稿記事 by 大工 » 16年前

なるほど

ですが,listを使うと添字を使ったアクセスが出来なくなってしまうのでvectorのままにします

reversですか…
いま携帯からアクセスしてるので詳しく調べられないのですが,
配列の順番が変わってしまうのでしょうか?

たかぎ

Re:コピーコンストラクタが呼ばれる回数

#4

投稿記事 by たかぎ » 16年前

> reversですか…

reversではなくreserveです。
あらかじめ確保すべき領域のサイズを予約しておくためのものです。
配列の順序は関係ありません。

大工

Re:コピーコンストラクタが呼ばれる回数

#5

投稿記事 by 大工 » 16年前

あら…

お恥ずかしい^^;

グラフのサイズは有限ですのでその方法を取りたいと思います

閉鎖

“C言語何でも質問掲示板” へ戻る