c++11中新型for循环,auto, 类成员的初始化及左右值引用

#include <typeinfo>
#include <iostream>
#include <string>
#include <vector>
#include <iterator>

static void autoValue();
static void autoPointer();
static void newVersionFor();
static void newVersionConstruct();
static void defaultInitValue();
static void leftRefAndRightRef();

//自定义类实现新型for循环
class MyVector {
    public:
        using GroupType = std::vector<int>;
    public:
        GroupType m_group;
        void push_back(int x) {
            m_group.push_back(x);
        }
};

MyVector::GroupType::iterator begin(MyVector &v) {
    return v.m_group.begin();
}
MyVector::GroupType::iterator end(MyVector &v) {
    return v.m_group.end();
}
void testMyClass() {

    MyVector mv;
    mv.push_back(1);
    mv.push_back(2);
    mv.push_back(3);
    for(auto i : mv) {
        std::cout << i << " ";
    }
    std::cout << std::endl;
}

int main(int /*argc*/, char** /*argv*/) {
    testMyClass();
    //new version auto
    //autoValue();
    //autoPointer();
//  newVersionFor();
    //newVersionConstruct();
//  defaultInitValue();
    leftRefAndRightRef();
    return 0;
}

static void autoValue() {
    auto age = 10;
    auto name = std::string("Yt");
    auto height = 160.0f;
    auto wight = 72.0;
    std::cout << "age is type " << typeid(age).name() << std::endl;
    std::cout << "name is type " << typeid(name).name() << std::endl;
    std::cout << "height is type " << typeid(height).name() << std::endl;
    std::cout << "weight is type " << typeid(wight).name() << std::endl;
}
static void autoPointer() {
    auto age = new int(10);
    auto name = "Yt";
    auto height = new float(160.0f);
    auto wight = new double(72.0);

    std::cout << "age is type " << typeid(age).name() << std::endl;
    std::cout << "name is type " << typeid(name).name() << std::endl;
    std::cout << "height is type " << typeid(height).name() << std::endl;
    std::cout << "weight is type " << typeid(wight).name() << std::endl;
}
static void newVersionFor() {
    int ids[] = {1, 2, 3, 4, 5};
    std::cout << "new version";
    for(auto v : ids) {
        std::cout <<  v << " ";
    }
    std::cout << std::endl;

    std::cout << "old version";

    for(int i = 0; i < sizeof(ids) / sizeof(ids[0]); ++i) {
        std::cout << ids[i] <<  " ";
    }
    std::cout << std::endl;

    //vector::
    std::vector<int> group;
    for(int i = 0; i < 4; ++i) group.push_back(i);
    //old version:
    //老版本遍历方式
    for(std::vector<int>::size_type i = 0, size = group.size(); i < size; ++i) {
        //cout << group[i] << " ";
    }
    //通过迭代器来遍历
    std::cout << "iterator: " << std::endl;
    //-------对于迭代器自增的时候,要用前置操作符,不要用后置操作符. ++iter, 若使用后置操作符号
    //多了一个步骤,就是把自增前的值先保留起来, 然后在自增.无用功
    for(std::vector<int>::const_iterator iter = group.begin(); iter != group.end(); ++iter) {
        std::cout << *iter << " ";
    }

    std::cout << std::endl;
    //auto version
    std::cout << "vector old version:" << std::endl;
    for(auto v : group) {
        std::cout << v << " ";
    }

    std::cout << std::endl;
    std::cout << "vector new version:" << std::endl;
    for(auto &v : group) {
        v = 1;
    }
    for(const auto &v : group) {
        std::cout << v << " ";
    }
}

class A {
    public:
        //why explicit ?? 具体含义是什么?
        explicit A(int value) : m_value(value) { }

    private:
    int m_value;
};

static void newVersionConstruct() {

    A a(10);
    A b{3};

    //old
    int avector[] = {1, 2, 3};
    std::vector<int> bv;
    for(auto v : avector) bv.push_back(v);

    //new
    std::vector<int> cv = {1, 2, 3};
    std::vector<int> v {1, 2, 3};

    A c(true);
    A d(false);

    A e(1.0);
    // A f{1.0} //不能做构造, 只能提高精度, 不能丢失
}

class B {
    public:
        B() : m_age(18), m_height(170), m_weight(75) {}
        explicit B(int age) : m_age(age), m_height(170), m_weight(75) {}
        B(int age, int height) : m_age(age), m_height(height) {}
        int age() const { return m_age; }
        int height() const { return m_height; }
        int weight() const { return m_weight; }
    private:
        int m_age;
        int m_height;
        int m_weight;
};

class NewB {
    public:
        NewB() {}
        explicit NewB(int age) : m_age {age} {}
        NewB(int age, int height) : m_age{age}, m_height {height} {}
        int age() const { return m_age; }
        int height() const { return m_height; }
        int weight() const { return m_weight; }
        void p() const { std::cout << m_value << " " << m_fightValue;}

    private:
        int m_age = 18; //初始化, 放置出现bug
        int m_height = 170;
        int m_weight = 75;
        int m_value{}; //代表拿int的默认值来作初始化,也就是0
        double m_fightValue{}; //0.0
};

static void defaultInitValue() {
    B a(10, 20);
    NewB b(10, 20);

    std::cout << "Old a age is" << a.age() << "height " << a.height()
        << " wight " << a.weight() << std::endl;

    std::cout << "New b age is" << b.age() << "height " << b.height()
        << " wight " << b.weight() << std::endl;

    b.p();
}

static void leftRefAndRightRef() {
    //什么是引用
    //引用类似与指针, 不同之处在于, 指针可以为nullptr, 但引用不可以
    int a = 10;
    int &refA = a;
    const int &constRefA = a;
    std::cout << " a" << a << " ref of a " << refA << " const ref a "
        << constRefA << std::endl;
    //this is a error
    // int &refB = 10;
    const int &constRefB = 10; //不管左值还是右值,都能赋给const 引用
    std::cout << "different version const ref " << constRefB << std::endl;

    //auto &&rrB = 20; //与下一样
    int &&rrB = 20;
    const int &&crrB = 20;

    rrB = 30; //可以改变右值, 其实只是改变那个值而已
    std::cout << " right ref of b " << rrB << " const right ref b "
        << crrB << std::endl;
    int b = 20;
    int &&newRRB = std::move(b); //强行转为右值
    const int &&cNewRRB = std::move(b);
    std::cout << " b " << b << " right ref of be " << newRRB << "const right ref b "
        << cNewRRB << std::endl;
    std::cout << "address " << &b << " ref " << &newRRB << " c ref " << &cNewRRB << std::endl;

}

原文地址:https://www.cnblogs.com/lyxf/p/12358350.html

时间: 2024-11-09 00:53:08

c++11中新型for循环,auto, 类成员的初始化及左右值引用的相关文章

Java 类成员的初始化顺序

Java 类成员的初始化顺序 前言:开发中碰到一个Java文件中有很多的成员变量,包括静态和非静态的,还有很多的初始化方法,很好奇这些成员的初始化顺序,在这里作个研究. ? 1 ?无继承情况下的Java初始化顺序: class Sample { Sample(String s) { System.out.println(s); } Sample() { System.out.println("Sample默认构造函数被调用"); } } class Test { static Samp

类成员变量初始化的问题

class window{ window(int maker){ System.out.println("window"+maker); } } class House{ window w1 ;//new window(1); window w3 = new window(3); House(){ System.out.print("House"); w3 = new window(33); } window w4 = new window(4); } class

类成员变量初始化

C++类对象的构造顺序是这样的:分配内存->调用构造函数时,隐式/显式的初始化各数据成员->在构造函数内部初始化数据成员. C++类初始化需注意以下几点 1.类里面的任何成员变量在定义时是不能初始化的.    2.一般的数据成员可以在构造函数中初始化.(构造初始化列表初始化和构造函数体内赋值初始化)    3.const数据成员必须在构造函数的初始化列表中初始化.(道理很简单,const成员第一次数据初始化就是发生在类构造数据初始化时,一旦过了此时就会出现问题).    4.static在类的

c++——继承类中的子对象和基类对象的初始化

先给结论: (1)派生类中的基类子对象和子对象必须初始化,初始化在派生类的构造函数的初始化列表中,如果初始化列表中没有进行初始化,则调用缺省的构造函数进行初始化. (2)派生类构造函数的调用顺序: 基类的构造函数 子对象类的构造函数 派生类的构造函数 例子 class point1 { public: point1(); point1(int i); virtual ~point1(); private: int x; }; point1::point1() { x=1; cout<<&quo

C++构造函数对类成员变量初始化,使用初始化列表和构造函数内部直接赋值 的差别

初始化和赋值对内置类型的成员没有什么大的差别,像任一个构造函数都能够. 但有的时候必须用带有初始化列表的构造函数: (1) 成员类型是没有默认构造函数的类.若没有提供显式初始化时,则编译器隐式使用成员类型的默认构造函数,若类没有默认构造函数,则编译器尝试使用默认构造函数将会失败. (2) const成员或引用类型的成员.由于const对象或引用类型仅仅能初始化,不能对他们赋值. 另一个赋值次数,效率上的差别: 初始化參数列表在对象初始化时对成员变量赋值一次. 构造函数内直接赋值,对成员变量赋值两

c++ 类成员的初始化顺序

1 class TestClass1 2 { 3 public: 4 TestClass1() 5 { 6 cout << "TestClass1()" << endl; 7 } 8 TestClass1(const TestClass1&) 9 { 10 cout << "TestClass1(const TestClass1&)" << endl; 11 } 12 TestClass1(int i)

c++11 中的 move 与 forward

一. move 关于 lvaue 和 rvalue,在 c++11 以前存在一个有趣的现象:T&  指向 lvalue (左传引用), const T& 既可以指向 lvalue 也可以指向 rvalue.但却没有一种引用类型,可以限制为只指向 rvalue.这乍看起来好像也不是很大的问题,但其实不是这样,右值引用的缺失有时严重限制了我们在某些情况下,写出更高效的代码.举个粟子,假设我们有一个类,它包含了一些资源: class holder { public: holder() { res

C++11中的继承构造函数

时间:2014.06.19 地点:基地 ------------------------------------------------------------------------- 一.问题描述 在继承体系中,如果派生类想要使用基类的构造函数,需要在构造函数中显式声明.如下: struct A { A(int i){} }: struct B:A { B(int i):A(i){} }; 在这里,B派生于A,B 又在构造函数中调用A的构造函数,从而完成构造函数的传递. 又比如如下,当B中存

js中java式的类成员

function Range(from,to,x){ //实例(对象)字段 this.x=x; } //类字段 Range.Y="类字段"; //类方法 Range.s=function(){ return '类方法'; }; Range.prototype={ constructor:Range, //实例方法 slff:function(){ return "实例方法"; } }; var s=new Range(1,3,"实例字段"); c