shonen.hateblo.jp

やったこと,しらべたことを書く.

C++ の継承でよく見かける virtual について

何度も調べているので,もう自分でまとめた.

参考資料

http://www.yunabe.jp/docs/cpp_virtual_destructor.html

virtual に関する実験

#include "bits/stdc++.h"
using namespace std;

struct A{
    int x;
    A(int _x = 1):x(_x){
        cout << "construct A : " << x << endl;
    }
    virtual ~A(){
        cout << "destruct A : " << x << endl;
    }
    virtual void func(){
        cout << "func A : x=" << x << endl;
    }
};

struct B: public A{
    int y;
    B(int _y = 2, int _x = 1):A(_x),y(_y){
        cout << "construct B : " << x << ',' << y << endl;
    }
    ~B(){
        cout << "destruct B : " << x << ',' << y << endl;
    }
    void func(){
        cout << "func B : y=" << y << endl;
    }
};

int main(){
    unique_ptr<A> ptr;
    ptr.reset(new A(10));
    ptr->func();
    ptr.reset(new B(20, 30));
    ptr->func();
    
    A* p = new B(9, 99);
    p->func();
    delete p;
    
    return 0;
}

結果.

construct A : 10
func A : x=10
construct A : 30
construct B : 30,20
destruct A : 10
func B : y=20
construct A : 99
construct B : 99,9
func B : y=9
destruct B : 99,9
destruct A : 99
destruct B : 30,20
destruct A : 30

A*B* を代入しても,B 側のメソッドが呼ばれる.デストラクタも同様.

かなり不思議な挙動だと思いませんか? 変数 A* p の気持ちになって観察すると,A のポインタが入っているはずなので,p->func()A::func() を呼び出すはず.

仕掛け

仮想関数テーブル (vtable) と呼ばれる機構があり,メソッドに virtual と修飾するだけで,適切な関数が呼び出されるよう「動的に」解決してくれる.

動的に解決する以上,ある程度のオーバーヘッドが発生する.

どの程度のオーバーヘッドが気になるならば,virtual 禁止縛りで書いてみると面白いかもしれない.

#include "bits/stdc++.h"
using namespace std;

struct A{
    const char type; // todo: うまいこと隠す
    int x;
    A(int _x = 1, char _type = 'A'):type(_type), x(_x){
        cout << "construct A : " << x << endl;
    }
    ~A();
    void func();
};

struct B: public A{
    int y;
    B(int _y = 2, int _x = 1):A(_x, 'B'),y(_y){
        cout << "construct B : " << x << ',' << y << endl;
    }
    void _delB(){
        cout << "destruct B : " << x << ',' << y << endl;
    }
    void _func(){
        cout << "func B : y=" << y << endl;
    }
};

A::~A(){
    if (type == 'B') ((B*)this)->_delB();
    cout << "destruct A : " << x << endl;
}
void A::func(){
    if (type == 'B') ((B*)this)->_func();
    else
        cout << "func A : x=" << x << endl;
}

int main(){
    
    unique_ptr<A> ptr;
    
    ptr.reset(new A(10));
    ptr->func();
    ptr.reset(new B(20, 30));
    ptr->func();
    
    A* p = new B(9, 99);
    p->func();
    delete p;
    
    return 0;
}

汚い

立方体の各面にテクスチャを貼る - three.js アプリ 制作メモ 1

HelloWorld(https://threejs.org/docs/index.html#manual/introduction/Creating-a-scene)の次からいきなり詰んだので記事書きました .

環境

  • 0.95.0 from npm

dom操作が苦手なので必要以上にjqueryが登場しますが,その場合はv3とします.

続きを読む

古いGCCのシフト演算子の評価値の拾い方が違う

C++コンパイラ依存シリーズ

古いGCCの評価値の拾い方がおかしい.

・・・こんなコードはまず書かないだろうけれど.

code

#include <iostream>
using namespace std;

int main(){
    int x = 0;
    auto f = [&x](){return ++x;};
    cout << x << f() << f() << f() << x << endl;
    return 0;
}
続きを読む

(楕円)円運動っぽいアニメーションの実装

目的

divが円運動するようなアニメーションを作る.

下のgifはカクついていますが,実際のアニメーションは一応ぬるぬる動きます.

https://i.gyazo.com/e3437d02415d5d2a7a7d5045dd1618b3.gif

続きを読む

whitespace(esolang) メモのまとめ

2018/08/10 ヒープ操作追記

2018/09/06 負整数について追記

whitespaceとは

  • esolang
  • スタックベース

参考URL

  • [https:;hackage.haskell.org/package/whitespace-0.4/src/docs/tutorial.html]
  • 以下,「本家」と呼ぶものはwspace 0.3 (ideoneで試せるもの)とする.

以降の表記

空白は見にくいので,次のように表記する

  • 半角スペース S
  • タブ T
  • LF改行 L

読みやすさのために,スペースやアンダーバーを入れることがある.

whitespace 0.3と0.4の違い

  • shuffleが実装されている
    • スタックをランダムに並び替える S_TTS 命令がある
続きを読む

gprof を触りだけ

gprofとは

プロファイラ.

参考

https://www.howtoforge.com/tutorial/how-to-install-and-use-profiling-tool-gprof/

環境

paiza cloud.

~$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
~$ gprof --version
GNU gprof (GNU Binutils for Ubuntu) 2.26.1
Based on BSD gprof, copyright 1983 Regents of the University of California.
This program is free software.  This program has absolutely no warranty.

(bash on ubuntu) は関数がうまく拾えないのか,何も表示されませんでした.(バージョン違いかも?)

続きを読む

クエリちゃん x プロ生ちゃん 夏休み #プチプログラミング コンテスト2018 に応募しました

気軽なイベントらしいので,気軽なコード(?)を書きました(?).

夏休みプチプログラミングコンテスト2018 とは

テーマ『夏休みの宿題(小学生な感じの夏休みをイメージ)』に沿った短め(長めでもOK)のコードを投稿するイベント.

pronama.azurewebsites.net

作ったもの

サンプルが算数ドリルを生成するコードだったので, 夏休み中の出校日をイメージして(?),算数ドリルの丸付けのコードを書きました.

続きを読む