• effective C ++ 学习笔记之 item 31 将文件间的编译依赖关系降至最低(未完成)


    1. 由于本例中使用了 boost 的shared_ptr,先看一个shared_ptr:shared_ptr使用的是引用计数方式

    #include <string>
    #include
    <iostream>
    #include
    <boost/shared_ptr.hpp>
    using namespace std;
    class implementation
    {
    public:
    ~implementation()
    {
    cout
    << "析构函数" << endl;
    }

    void f()
    {
    cout
    << "函数f()" << endl;
    }
    };
    int main()
    {
    boost::shared_ptr
    <implementation> sp1(new implementation());
    cout
    << "use_count():" << sp1.use_count() << endl;

    boost::shared_ptr
    <implementation> sp2 = sp1;

    cout
    << "use_count():" << sp2.use_count() << endl;

    sp1.reset();
    cout
    << "use_count():" << sp2.use_count() << endl;

    return 0;
    }

      2. 关于前向声明的使用:一般尽量使用指针

    #include <iostream>
    
    using namespace std;
    class A;
    class B
    {
        public:
        B(A *a1);
        void f();
        private:
        A *a;
    };
    class  A
    {
        public:
        A(string name)
        {
            this->name = name;
        }
        void d()
        {
            cout << name << endl;
        }
    
    
        string name;
    };
    void B::f()
    {
        cout << a->name <<  endl;
        //cout << a.name << endl;  a 是一个指针
        //cout << a->d() << endl;  
        //cout << a.d() << endl;
    }
    B::B(A *a1)
    {
        a = a1;
    }
    int main()
    {
        A a("hello");
    
        A *p = &a;
        B b(p);
        b.f();
        return 0;
    }
    

      如果上面的A中的name是private的,使用a.name也会报错

       error: 'std::string A::name' is private,这是因为name是private,出了A的作用域了

    另外还有一个前向声明的问题:

    class B;
    class A
    {
    public:
    void f(B b);
    };
    class B
    {
    public:
    void g(A a);
    };

    //上面的是可以的,下面的不行,也就是说做形参可以(返回值也行)
    class A;
    class B
    {
    A x;
    }
    class A
    {
    B y;
    };

      因为前向声明并没有给出类的定义,此时只能定义指针和引用,也就是上面的例子的那样,不能定义对象,可以作为形参,因为没有定义对象,而第2个定义对象了

        但是一个例外是使用static,静态的数据成员不再类内部,在静态存储区,因此类体有完整的定义,可以创建对象

    例如下面的就可以通过编译

    #include <iostream>

    using namespace std;
    class B;
    class A
    {
    public:
    void f()
    {
    cout
    << "A::f()" << endl;
    }
    private:
    static B b;
    };
    class B
    {
    public:
    void f()
    {
    cout
    << "B::f()" << endl;
    }
    private:
    A a;
    };
    int main()
    {
    A a;
    B b;

    return 0;
    }

      但是如果是作为构造函数的参数是不能通过的,因为构造函数是创建对象的时候调用的

    另外一个前向声明的问题,下面代码中第8行,A中如果没有构造函数A(){}就会报错,B()中可以没有,这与static静态成员变量有关

     1 #include <iostream>
    2
    3 using namespace std;
    4 class B;
    5 class A
    6 {
    7 public:
    8 A(){} //如果没有A(){}默认的构造函数而出现 error: no matching function for call to 'A::A()'
    9
    10
    11 A(string name)
    12 {
    13 name_a = name;
    14 }
    15
    16 void f()
    17 {
    18 cout << "A::f()," << name_a << endl;
    19 }
    20 private:
    21 static B b;
    22 string name_a;
    23 };
    24 class B
    25 {
    26 public:
    27 //但是B中就可以没有B() {}
    28 B(string name)
    29 {
    30 name_b = name;
    31 }
    32
    33 void f()
    34 {
    35 cout << "B::f()," << name_b << endl;
    36 }
    37 private:
    38 A a;
    39 string name_b;
    40 };
    41 int main()
    42 {
    43 A a("helloa");
    44 B b("hellob");
    45 a.f();
    46 b.f();
    47
    48 return 0;
    49 }

      下面的将static注释掉,则运行正确!如下:

    #include <iostream>

    using namespace std;
    class B;
    class A
    {
    public:
    // A(){} //如果没有A(){}默认的构造函数而出现 error: no matching function for call to 'A::A()'


    A(
    string name)
    {
    name_a
    = name;
    }

    void f()
    {
    cout
    << "A::f()," << name_a << endl;
    }
    private:
    // static B b;
    string name_a;
    };
    class B
    {
    public:
    //但是B中就可以没有B() {}
    B(string name)
    {
    name_b
    = name;
    }

    void f()
    {
    cout
    << "B::f()," << name_b << endl;
    }
    private:
    // A a;
    string name_b;
    };
    int main()
    {
    A a(
    "helloa");
    B b(
    "hellob");
    a.f();
    b.f();

    return 0;
    }

      原因是static在静态存储区,是可以创建对象的,有完整定义,但是也是到用的时候才创建

    3. 接口与实现分离的简单例子,下面将struct换成class就不行了

    #include <iostream>

    using namespace std;
    struct Interface
    {
    void (*f)();//定义一个指针函数
    };
    void f1()
    {
    cout
    << "f1()" << endl;
    }
    void f2()
    {
    cout
    << "f2()" << endl;
    }
    int main()
    {
    Interface a;
    a.f
    = f1;
    a.f();
    a.f
    = f2;
    a.f();
    return 0;
    }

      

  • 相关阅读:
    minlo 开源对象存储系统
    Oracle PDB的相关使用说明
    阿里云ECS虚拟机磁盘扩容过程
    CentOS firewall简单总结
    Redis 的简单学习与整理
    【Python】psutil系统信息获取 规格严格
    rsyslog和logrotate的使用 规格严格
    myisamchk: error: 140 when opening MyISAMtable 规格严格
    查看文件的时候报错input.output error 规格严格
    NLP材料的一些笔记
  • 原文地址:https://www.cnblogs.com/hitwtx/p/2158872.html
Copyright © 2020-2023  润新知