Rodhos Soft

備忘録を兼ねた技術的なメモです。Rofhos SoftではiOSアプリ開発を中心としてAndroid, Webサービス等の開発を承っております。まずはご相談下さい。

チュートリアル的な記述4

ファイル操作

#include <iostream>
#include <fstream>


void fileSample() {
    // file
    std::ofstream ofs("test.txt");
    if (!ofs) {
        std::cerr << "[error]open file" << std::endl;
        std::exit(1);
    }
    ofs << "Hello, World\n123" << std::endl; // auto close
    
    std::ifstream ifs("test.txt");
    if (!ifs) {
        std::cerr << "[error]open file for ifstream." << std::endl;
        std::exit(1);
    }
    
    std::string bufstr;
    ifs >> bufstr;
    
    std::cout << bufstr << std::endl; //[note] output is Hello,
    
    
    std::ifstream ifs2("test.txt");
    if (!ifs2) {
        std::cerr << "[error]open file for ifstream." << std::endl;
        std::exit(1);
    }
    std::string bufstr2;
    getline(ifs2, bufstr2);
    std::cout << bufstr2 << std::endl; //[note] output is Hello, World
    
    getline(ifs2, bufstr2);
    std::cout << bufstr2 << std::endl; //[note] output is 123
    
    if (ifs2.eof()) {
        std::cout << "eof" << std::endl; //[note] output is 123
    }
}

チュートリアル的な記述3

変数

#include <sstream>
#include <iomanip>
#include <fstream>
void basicVariable() {
    const int c = 10;
    
    // ref
    int r = 0;
    int& r2 = r;
    r2 = 100;
    std::cout << r << std::endl; // 100
    
    // 構造体
    Point p;
    p.x = 10;
    p.y = 10;
    std::cout << p.d2() <<std::endl;
    
    // enum
    // enum
    ColorType1 type1 = ColorType1::RED;
    ColorType2 type2 = ColorType2::RED;
    ColorType3 type3 = ColorType3::RED;
    
    ColorType1 type4 = RED;
    //    ColorType2 type5 = RED; できない
    //    ColorType3 type6 = RED; できない
    
    std::cout << type1 << std::endl;
    std::cout << static_cast<int>(type2) << std::endl;
    std::cout << static_cast<int>(type3) << std::endl;
    std::cout << type4 << std::endl;
    
    // auto 型推論
    auto x = "x";
    
    // 文字列
    std::string z = "ac";
    auto y = 3.0;
    auto z1 = z + z;
    auto z2 = x + z;
    auto z3 = z + x;
    std::string z5 = z.append(x); // acx
    std::string z6 = z.append(z); // acxacx
    
    z.empty();// empty check
    
    //auto z4 = x + x; //できない。 const char*
    std::cout << x << std::endl;
    std::cout << y << std::endl;
    std::cout << z << std::endl; // acxacx
    std::cout << z5 << std::endl;// acx
    std::cout << z6 << std::endl;// acxacx
    
    // decltype
    int sample = 100;
    decltype(sample) sample2 = 200; // Type of sample2 is Int.
    decltype(getValue()) sample3 = 3.3;//  Type of sample3 is Int.
    std::cout << sample << sample2 << sample3 << std::endl;
    
    
    // escape
    std::string stresc = "a\nb\nc";
    std::string stresc2 = R"(a
    b
    c)";
    std::cout << stresc << std::endl;
    std::cout << stresc2 << std::endl;
    
    // null pointer
    int* a = nullptr;
    if (a == nullptr) {
        std::cout << "nullptr" << std::endl;
    }
}

文字列

#include <iostream>
void stringUse() {
    std::string x = "aaa";
    std::string y = "bbb";
    std::string z = x + y;
    
    std::cout << z << std::endl;

}

ベクトル

#include <iostream>
#include <vector>
void vectorUse() {
    
    std::vector<int> v = {1,5,10,100};
    
    v[2] = 100;
    
    v.push_back(50);
    
    /// もっと簡単に表示してしたい
    for (int x: v) {
        std::cout << x << std::endl;
    }
    
    std::vector<int> v2 = {1,3,2,5};
    
    /// +は使えないのだろうか。 C++にカテゴリ拡張はない。
    v2.insert(v2.end(), v.begin(), v.end());
    
    
    /// coutが面倒だ。。
    std::cout << "v2" << std::endl;

    for (int x: v2) {
        std::cout << x << std::endl;
    }

}

チュートリアル的な記述2

参照

// class
class CPYCost {
    
public:
    CPYCost();
    ~CPYCost();

    /// オブジェクトのコピー用の代入演算子
    CPYCost& operator=(const CPYCost& rhs);
    int x;
    
private:
};
void refAdd(int &x);
void pAdd(int *x);


void refUse() {
    
    // 参照
    int x = 1;
    int& r = x;// xの参照を取得
    r = 2; // xは2になる。
    // 参照はNULLを代入できない。
    
    // ポインタ
    int z = 1;
    int* p = &z;
    *p = 2; // zは2になる。
    
    int t = 10;
    refAdd(t); // tが11になる。
    pAdd(&t); // tが12になる。
    
    CPYCost *c = new CPYCost();
    c->x = 1000;
    
    CPYCost d;
    d.x = 2500;
    CPYCost &dd = d;
    CPYCost ddd = d;
    
    std::cout << ddd.x << std::endl;

    
         
}

void refAdd(int &x) {
    x++;
}

void pAdd(int *x) {
    (*x)++;
}

ラムダ式

void lambdaUse() {
    auto l = [](int x)->int {
        return x+3;
    };
    int x = l(5);
    
    // NG
//    auto l2 = [](int a)->int {
//        return x+10;
//    };
    
    // xをキャプチャ
    auto l2 = [x](int a)->int {
        return x+10;
    };
    
    // すべてキャプチャ
    auto l4 = [=](int a)->int {
        return x+10;
    };

    std::cout << x << std::endl;

}

チュートリアル的な記述

関数

int twice(int x);
int twice(int x) {
    return x * 2;
}
auto nfunc2(int x) -> decltype(x) {
    return x * 100;
}
namespace FunctionauUse {
    int add(int x);
    void echo(int x);

}

/// 関数を変数に格納する。
void functionalUse() {
    std::function<void(int)> f = FunctionauUse::echo;
    std::function<void(int)> f2 = FunctionauUse::add;
    f(3);
    f2(5);
}

void FunctionauUse::echo(int x) {
    
}

int FunctionauUse::add(int x) {
    return x+1;
}

テンプレート

template <typename R, typename T1, typename T2>
R echo(T1 x, T2 y) {
    return static_cast<R>(x+y);
}

構造体

struct Point {
    int x;
    int y;
    int d2(); // メソッド生やせる。
};
int Point::d2() {
    return this->x + this->y;
}

クラス

// class
class Man {
    
public:
    void hello();
    
    Man(); // default constructer
    Man(std::string name);
    
    ~Man();
    
    //    static int commonNumber;
    bool operator==(const Man& rhs) const;
    
    inline bool operator!=(const Man& rhs) const {
        return !(*this == rhs);
    }
    
    
private:
    std::string name;
    int age;
    void util();
    int n = 10;
};

void Man::hello() {
    std::cout << "Hello, my name is " << this->name << std::endl;
    
}

void Man::util() {
    std::cout << "util" << std::endl;
    
}

Man::Man() : name("name"), age(0){
    //    commonNumber++;
}

Man::Man(std::string name) {
    this->name = name;
    age = 0;
    //    commonNumber++;
}

Man::~Man() {
    std::cout << "dec" << std::endl;
}

void hello(Man *m) {
    m->hello();
}

bool Man::operator==(const Man &rhs) const {
    return name == rhs.name;
}



void classUse() {
    /// クラス
    Man *man = new Man();
    man->hello();
    delete man;
}

テンプレート使用

template <typename T>
class Poi {
public:
    void echo(T x);
};

template <typename T>
void Poi<T>::echo(T x) {
    std::cout << "echo" << x << std::endl;
}

enum

enum ColorType1 : int {
    GREEN,RED,YELLOW
};

enum struct ColorType2 : int {
    GREEN,RED,YELLOW
};

/// enum structとenum class は同じ
enum class ColorType3 : int {
    GREEN,RED,YELLOW
};

namespace

namespace spaceA {
    double getValue();
    
    namespace specialB {
        double getValue();
    }
    
    inline namespace Util {
        double getUtilValue();
    }
}

namespace {
    const int myMAX2 = 100;
}

namespace spaceMAX {
    const int myMAX = 1000;
}

void nameSpaceUse() {
    /// 名前空間
    auto v = getValue();
    auto v2 = spaceA::getValue();
    auto v3 = spaceA::specialB::getValue();
    auto v4 = spaceA::getUtilValue();
    
    using namespace spaceA;
    auto v5 = getUtilValue();
    
    /// alias
    namespace B = spaceA::specialB;
    auto b = B::getValue();
    
    std::cout << v << std::endl;
    std::cout << v2 << std::endl;
    std::cout << v3 << std::endl;
    std::cout << v4 << std::endl;
    
    auto max = spaceMAX::myMAX;
    auto max2 = myMAX2;
    
    std::cout << max << max2 << std::endl;

}

double getValue() {
    return 2.0;
}

namespace spaceA {
    double getValue() {
        return 20.0;
    }
    
    
    namespace specialB {
        double getValue() {
            return 30;
        }
    }
    
    
    inline namespace Util {
        double getUtilValue() {
            return 50;
        }
    }
    
}

開発用サーバ

WebPackの開発用サーバを使う。

webpack-dev-serverをnpmでインストール。

webpack.config.jsに

devServer: {
  contentBase: path.resolve(__dirname, 'app'),
  port: 3000
}

を等と設定、また、outputのpublicPathも追加してcontentBaseに合わせておく(そうしないとpath:を起点にjs等が参照されてしまう。)。

output: {
  path: path.resolve(__dirname, 'app/dist'),
  publicPath: "app/"
},

npmにコマンドを登録し

"scripts": {
     "server": "webpack-dev-server --inline",
   }

npm run server等とやればlocalhost:3000でアクセスできる。

履歴をしらべてコピーする。

履歴を調べて古かったらコピーするというスクリプトを書いてみた。 makefileの代わりに

import sys
import os
import shutil
import re

# pathlistで指定したフォルダのファイルに対応するファイルがbasepath以下にある場合、basepathの方が古くなっていたらコピーする。
basepath = "./tmp/"
pathlist = ["./dist","./html","./lib"]

def fileList(path):
    list = []
    for root,dirs,files in os.walk(path):
        t = [os.path.join(root,f) for f in files]
        list.extend(t)
    return list

def isLeftPathIsNew(path1, path2):
    if not os.path.exists(path1):
        return False
    if not os.path.exists(path2):
        return False
    time1 = os.stat(path1).st_mtime
    time2 = os.stat(path2).st_mtime
    # print(path1 + str(time1) + ">=" + path2 + str(time2))
    if time1 >= time2:
        return True
    return False

for path in pathlist:
    # print("\n")
    fList = fileList(path)
    for f in fList:
        reg = r'\..*'
        if re.match(reg, os.path.basename(f)):
            # print("Skip" + f)
            continue
        tf = basepath + f[2:]
        if isLeftPathIsNew(tf,f):
            # print("new!"+tf)
            continue
        else:
            print("old!"+tf)
            dir = os.path.dirname(tf)
            if not os.path.exists(dir):
                print("makedir", dir)
                os.makedirs(dir)

            shutil.copy(f,tf)


plugin

webpack plugin

webpack pluginは

  apply(compiler) {}

を持つクラスとして定義して、 webpack.config.jsにおいて

  plugins: [
  new HelloPlugin()
]

のように入れてやれば良い。

const pluginName = 'HelloPlugin';

class HelloPlugin {
    apply(compiler) {
        compiler.hooks.run.tap(pluginName, compilation => {
            console.log("Hello");
        });
    }
}

hookの内容は

Compiler Hooks

localhostの場所の確認

サーバ確認 httpdはhttpデーモン このhttpデーモンがapacheか確認する。 httpd -v

これがapacheと出たら つまりapacheのコマンド  apachectl と同じということ。

コンフィグファイル(/httpd.conf)の場所を調べる。 httpd -V

conf内の DocumentRootの場所を調べる。

初歩

javaプラグインの使用

build.gradle

apply plugin: 'java'

プロジェクトとタスク

プロジェクトは複数のタスクから構成される。

タスク

分割不可能な作業単位

build.gradle

task hello << {
    println 'Hello world!'
}

実行は

gradle -q hello

-qはログの抑制

タスクの依存

task hello << {
    println 'Hello world!'
}
task intro(dependsOn: hello) << {
    println "I'm Gradle"
}

あとから依存関係を追加

task hello << {
    println 'Hello world!'
}
task intro << {
    println "I'm Gradle"
}

hello.dependsOn intro

タスクにアクションの追加

task hello << {
    println 'Hello world!'
}

hello.doFirst {
    println "I'm Gradle"
}

doLast(これは<<と同じ)等

拡張タスクプロパティ

 task hoge {
   ext.foo = "4"
 }

task poi << {
  println hoge.foo
}

 メソッドの使用

task hoge {
  ext.foo = "4"
}

デフォルトタスク

defaultTasks 'clean', 'run'

コピー

task copy_jsapp(dependsOn: build) {
    println("copy jsapp/app")
    file("hoge").mkdir()
    file("hoge/poge.txt").text = "a"
    file("dist").mkdir()
    file("dist/tmp.txt").text = "b"
    copy {
        from 'hoge'
        into 'dist'
    }
  }

出力先

pathを絶対パスに変換してoutputで指定してやれば良い。

const path = require('path');
module.exports = {
  // or production
  mode: 'development',

  entry: {
    menu:'./src/main.ts'},


  output: {
    path: path.resolve(__dirname, 'app/dist')
  },