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;
}

  

原文地址:https://www.cnblogs.com/hitwtx/p/2158872.html