C++ でクラスを作ったり、メンバーを追加した場合、必ずやらなければならないことがあります。 それは 「コピーコンストラクター と 代入演算子 が必要か適切に判断する」ということです。 また、必要だったとして、これらを書く場合にも様々な注意点やテクニックがあります。 今回はコピーコンストラクターと代入演算子に関する話題についてまとめてみたいと思います。 なお、今回は Effective C++ の影響をかなり受けています。 Effective C++ と同じような内容を書くと問題あるかと思い、 それらに関してはサワリと本の項の参照先だけ書いています。 (項は第 2 版のものです) コピーコンストラクター、代入演算子 とは まず、この 2 つについて、概要を説明します。 コピーコンストラクターは 同じクラスのオブジェクトを引数にとるコンストラクター を指します。 Foo a; Foo b(a
自動定義と手動定義 自分で定義していない場合 この場合、 デフォルトコンストラクタ コピーコンストラクタ デストラクタ コピー代入演算子 が自動で定義されます。 class SerialCode { //空っぽだが... }; int main() { //普通に使える SerialCode a; //デフォルトコンストラクタ呼び出し SerialCode b(a); //コピーコンストラクタ呼び出し a = b; //コピー代入演算子呼び出し } 自動定義で、コピー関係(コピーコンストラクタ、コピー代入演算子)は、クラスのメンバ変数を全てコピーしてくれています。自分で定義するときは、この点に注意しましょう。 自分で定義した場合 1~4の内、自分で定義した部分は、自動で定義されません。 注)引数付きコンストラクタを定義するとデフォルトコンストラクタは自動で定義されません class Ser
菱形継承の概念図 菱形継承問題(ひしがたけいしょうもんだい、英: diamond problem)は、多重継承を伴うオブジェクト指向プログラミング言語において、クラス A を2つのクラス B と C が継承し、B と C の両方をクラス D が継承する際に発生するあいまいさを指す用語である。たとえば、クラス D にあるメソッドが A で定義された(かつ D においてオーバーライドされていない)メソッドを呼び出すとしたとき、B と C がそのメソッドを異なった形でオーバーライドしていたら、D は B と C のどちらのメソッドを継承するのか、という問題がある[1]。 例えば、クラス Button は クラス Rectangle(見た目のため)と Mouse(マウスイベントのため)を継承し、Rectangle も Mouse も Object クラスを継承しているとする。ここで Button
概要 optionalクラスは、任意の型Tの値を有効値として、あらゆる型に共通の無効値状態を表現できる型である。 このクラスには、大きく2つの用途がある: オブジェクトの初期化タイミングを遅延させる エラー報告のために、あらゆる型に共通の無効値表現を持たせる オブジェクトは定義した時点で初期化が行われるが、optionalクラスはその初期化タイミングを遅延させるために使用できる。この用途には、std::shared_ptrのようなスマートポインタを使用することもできるが、このクラスは動的メモリ確保を行わないため、リソース管理ではなく初期化タイミングを遅延させるだけであれば、このクラスの方が適している。 エラー報告について、このクラスを使用しない場合、従来の方法として有効値と無効値は、以下のように表現されていた: int型の場合、0以上の値を有効な値とし、エラーが起きたら負数を代入する ポイ
#include <cassert> #include <cstddef> #include <cstdint> int main() { // 整数値を代入する際は、波カッコ {} で囲むか、 // static_cast<std::byte>(0b1010)のようにする std::byte a{0b1010'1010}; std::byte b{0b0000'1111}; // ビット論理積 std::byte result = a & b; // 基底型に変換 unsigned char result_uc = static_cast<unsigned char>(result); assert(result_uc == 0b0000'1010); // 任意の整数型に変換 std::uint8_t result_u8 = std::to_integer<std::uint8_t>(
このページはC++11に採用された言語機能の変更を解説しています。 のちのC++規格でさらに変更される場合があるため関連項目を参照してください。 概要 「ラムダ式(lambda expressions)」は、簡易的な関数オブジェクトをその場で定義するための機能である。 この機能によって、「高階関数(関数を引数もしくは戻り値とする関数)」をより使いやすくできる。 auto plus = [](int a, int b) { return a + b; }; int result = plus(2, 3); // result == 5 ここでは、[](int a, int b) { return a + b; }というコードがラムダ式に当たる。このラムダ式は、「int型のパラメータを2つとり、それらを足し合わせたint型オブジェクトを返す関数オブジェクト」を定義している。ここでは戻り値の型を
matsutakegohan1の日記 - 関数をmapに 現在のC++ではswitchにstringを使用することはできない void func1() { cout << "func1" << endl; } void func2() { cout << "func2" << endl; } int main() { string str; switch (str) { // エラー! case "abc": func1(); break; case "xyz": func2(); break; default: cout << "not found" << endl; break; } return 0; } そこで、if文でだらだらと書くことになるのだが void func1() { cout << "func1" << endl; } void func2() { cout << "
目次 cppcheckという静的解析ツールを試してみました。 cppcheckはC/C++言語向け静的解析ツールですが、今回メモリリーク検出を目的として試してみました。 ビルド~インストールや試してみた結果について書いておきたいと思います。 目次 背景 cppcheckを試してみる ビルド ビルド時の注意点 cppcheckを動かしてみる 検出できたリークパターン 検出できなかったリークパターン manualを読んでみた。 感想 背景 C言語やC++でコードを書いていると否が応でもメモリリークの危険性と戦う必要があります。 リークをなくすためには、 動的メモリ確保を行わない メモリリークがないかしっかり試験する の2つのアプローチがあります。 私が普段仕事をしている組み込みソフトの開発では1の「動的メモリ確保を行わない」というアプローチは一般的です。 そもそも組み込み開発の場合、OSがない
2017年6月7日 Theolizer®最新版v1.1.0へ対応するために修正しました。 最新版のソース一式をGistに置いてます。 こんにちは。田原です。 TCP/IP通信と言えばsocketですが、これは何にでも対応できる低レベルなインタフェースなので その分使うのがたいへんです。Theolizer®の通信サンプルを開発するにはちょっと大掛かりになりすぎるので躊躇していました。しかし、Boost.Asioにstd::iostream形式でTCP/IP通信を行える機能が含まれていることが判りました。 そこで、Boost.Asioを使って家計簿データの送受信をやってみました。予想通り実に簡単に通信できましたので、ご紹介します。 今回作ったサンプルは、下記処理を行います。 家計簿データをサーバへ送信 サーバにて集計処理 集計結果だけをクライアントへ返却 クライアントで表示 TCP/IP通信で
インデックス 接続 接続待機 メッセージ送信 メッセージ受信 名前解決して接続 タイムアウトを設定する 接続 同期バージョン 同期バージョンの接続には、boost::asio::ip::tcp::socketクラスのconnect()メンバ関数を使用する。 接続先の情報はtcp::endpointに、IPアドレス文字列と、ポート番号の2つを指定する。 connect()の第2引数としてerror_codeを渡した場合には、接続失敗時にエラー情報がerror_code変数に格納される。 error_codeを渡さなかった場合には、接続失敗時にboost::system::system_errorが例外として投げられる。 #include <iostream> #include <boost/asio.hpp> namespace asio = boost::asio; using asio:
はじめに boost.Asioでは、非同期処理のタイムアウト処理を当然行うことが出来るが 一般的なソケットのような、関数にタイムアウト時間を設定するような簡易な方法ではない 非同期処理とは別に、タイマーWaitを非同期で書き、非同期処理が終了すればタイマーをキャンセルし タイマーが先に来れば 非同期処理をキャンセルしタイムアウト処理を行う という 冗長な処理が必要である それを、どのようにラップすればきれいに書けるのか?という話 まずはベタに書いてみる // タイムアウトを設定 deadline_timer.expires_from_now( boost::posix_time::milliseconds(timeout_ms)); deadline_timer.async_wait( [=](const boost::system::error_code &ec) { // タイムアウト
タイムアウトには、async系メソッドと別にdeadline_timerを動かし、タイムアウトを設定します。 タイムアウトの前に非同期処理が完了した場合はdeadline_timer::cancel()を呼び、タイムアウト用のタイマーをキャンセルします。 そうすると、タイムアウトのハンドラが呼ばれなくなる・・・のではなく!タイムアウトのハンドラにエラー(boost::asio::error::operation_aborted)が渡されるので、タイムアウトハンドラがエラーじゃなかった場合に実際のタイムアウト処理を行います。 以下、サンプルコード: #include <boost/asio.hpp> #include <boost/bind.hpp> #include <iostream> namespace asio = boost::asio; class Client { asio::
結論 C++をgdbでデバッグする時(特にポリモーフィズム使ってる場合)は、下記の設定をするとわかりやすいです。 gdb manual 背景 C++でポリモーフィズムすると、デバッグ時に実際のクラスがぱっと見わからなくて困ることがあります。 例として、以下のようなプログラムを考えます。 Animalクラスを基底クラスとして、そこから継承したクラスをいくつか定義しています。 それらのインスタンスへのポインタをstd::vectorでまとめて、 Chorus関数にてポリモーフィズムを使ったMakeSound呼出をしています。 #include <iostream> #include <memory> #include <vector> class Animal { public: virtual ~Animal() {} virtual void MakeSound() const { std
リリース、障害情報などのサービスのお知らせ
最新の人気エントリーの配信
処理を実行中です
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く