C++中final类的实现

namespace   Private{ 
class   NonDerivableHelper 
{ 
NonDerivableHelper()   {} 
friend   class   NonDerivable; 
}; 
} 
#ifdef   NDEBUG 
#define   FINAL_CLASS 
#else 
#define   FINAL_CLASS   :   private   virtual   Private::NonDerivableHelper 
#endif 
class   NonDerivable   FINAL_CLASS 
{ 
... 
}; 


在《C++ View》第一期P25,《C++中常用的几个小技巧》中,提供了实现final类的方法。
这里我们先不将方法写全,而是抽取其中精华的部分来看。
     在看代码之前,首先我们要了解的知识包括,构造函数,私有访问,友元,私有继承,虚拟继承,以及虚拟继承下的特殊初始化语义(虚拟基类的初始化变成了最终派生类的责任)。
这些可以参考《C++ Primer》第三版中的相关内容,因为内容较多,需要整理一下,再行发出。
1.构造函数                                              


     在《C++ View》第一期P25,《C++中常用的几个小技巧》中,提供了实现final类的方法。
这里我们先不将方法写全,而是抽取其中精华的部分来看。

     在看代码之前,首先我们要了解的知识包括,构造函数,私有访问,友元,私有继承,虚拟继承,以及虚拟继承下的特殊初始化语义(虚拟基类的初始化变成了最终派生类的责任)。
这些可以参考《C++ Primer》第三版中的相关内容,因为内容较多,需要整理一下,再行发出。
1.构造函数                                               -----       待整理
2.私有访问                                               -----       待整理
3.友元                                                      -----       待整理
4.私有继承
         private继承是因为父类提供了更多的接口,而子类并不需要这些接口来对外,子类只是在提供自己接口的时候,希望重用父类的实现。从而private继承父类,这样父类的公有方法在子类中全部成为了private方法,只有子类的成员函数和友元类可以访问这些方法,而其他使用均为非法。
5.虚拟继承                                               -----       待整理
6.虚拟继承下的特殊初始化语义               -----       待整理

所有代码均为完整代码,非代码片段,可以直接使用;所有代码均经过测试,测试平台VS2005。
一些代码不能编译通过,正是说明了语言特性,请联系上下文使用代码。
代码1:

#include <iostream>
using namespace std;

class NonDerivableHelper
{
private:
	NonDerivableHelper() 
	{
		cout<<"base1"<<endl;
	}
	friend class NonDerivable;
};
class NonDerivable:private NonDerivableHelper
{
public:
	NonDerivable():NonDerivableHelper()
	{
		cout<<"base2"<<endl;
	}
};

class Derive:public NonDerivable{
public:
	Derive():NonDerivable()
	{
		cout<<"Derive"<<endl;
	}	
};
int main()
{
	Derive d;
	return 1;
}

代码1中Derive类可以继承NonDrivable类,NonDerivable类可以使用NonDerivableHelper的私有

构造函数方法(因为NonDerivableHelper类声明NonDerivable类为其友元)。从而可以继承成功。

代码2:

#include <iostream>
using namespace std;

class NonDerivableHelper
{
private:
	NonDerivableHelper() 
	{
		cout<<"base1"<<endl;
	}
	friend class NonDerivable;
};
class NonDerivable:private virtual NonDerivableHelper
{
public:
	NonDerivable():NonDerivableHelper()
	{
		cout<<"base2"<<endl;
	}
};

class Derive:public NonDerivable{
public:
	Derive():NonDerivable()
	{
		cout<<"Derive"<<endl;
	}	
};
int main()
{
	Derive d;
	
	return 1;
}


在11行的类继承时,加上virtual继承,这样Derive类就无法再对NonDerivable类进行继承了,NonDerivable

即我们所要实现的final类。会在编译时出现错误。这时的疑问就是,无论如何都会出现无法继承吗?
OK,第一种情况:Derive类自己不实现构造函数,使用默认的构造函数。
代码3:
#include <iostream>
using namespace std;

class NonDerivableHelper
{
private:
	NonDerivableHelper() 
	{
		cout<<"base1"<<endl;
	}
	friend class NonDerivable;
};
class NonDerivable:private virtual NonDerivableHelper
{
public:
	NonDerivable():NonDerivableHelper()
	{
		cout<<"base2"<<endl;
	}
};

class Derive:public NonDerivable{
public:	
};
int main()
{
	Derive d;
	
	return 1;
}

这时我们编译发现,还是编译错误:cannot access private member declared in class 'NonDerivableHelper'
说明默认还是去调用了基类的构造函数。
第二种情况:
NonDerivable类也不去实现构造函数而使用默认构造函数。
代码4:
#include <iostream>
using namespace std;

class NonDerivableHelper
{
private:
	NonDerivableHelper() 
	{
		cout<<"base1"<<endl;
	}
	friend class NonDerivable;
};
class NonDerivable:private virtual NonDerivableHelper
{
public:

};

class Derive:public NonDerivable{
public:
	
};
int main()
{
	Derive d;
	
	return 1;
}

这时也会发现,同样的编译错误。
说明Derive类不是通过NonDerivable类来调用的基类的构造函数。
第三种情况,将NonDerivableHelper中的friend class NonDerivable的友元声明去掉。
代码5:
#include <iostream>
using namespace std;

class NonDerivableHelper
{
private:
	NonDerivableHelper() 
	{
		cout<<"base1"<<endl;
	}
};
class NonDerivable:private virtual NonDerivableHelper
{
public:

};

class Derive:public NonDerivable{
public:
	
};
int main()
{
	Derive d;
	
	return 1;
}


这时还是和上面报的一样的错误。Derive不能访问基类的private方法。
第四种情况:将NonDerivableHelper中的friend class NonDerivable的友元声明去掉。将NonDerivable
的继承修改为private继承。

代码6:

这时我们发现,编译错误改变了,现在是NonDerivable类不能访问NonDerivableHelper类的private
构造函数了。这也是正确的,因为只有该类的友元与该类的成员函数可以访问private成员,而子类是不
可以的。
这个例子与下面的相同:
1 #include <iostream>  
 2 using namespace std;
 3   
 4 class NonDerivableHelper
 5 {
 6 private:
 7        NonDerivableHelper() {cout<<"Base1"<<endl;}
 8     friend class NonDerivable;
 9 };
10  
11 class NonDerivable:private NonDerivableHelper
12 {
13 private:
14        NonDerivable() {}
15 };
16  
17 class Derive:public NonDerivable
18 {
19  
20 };
21  
22 int main()
23 {
24        Derive d;
25 }

此时,编译错误。Derive不能够访问父类NonDerivable的对象。
从上面的代码可以了解virtual继承,private访问控制,友元的一些关系。
以下是 C 语言实现 MD5 的代码: #include <stdio.h> #include <string.h> #include <stdint.h> #define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c)))) void md5(const uint8_t *initial_msg, size_t initial_len, uint8_t *digest) { // These vars will contain the hash uint32_t h, h1, h2, h3; // Message (to prepare) uint8_t *msg = NULL; // Message length in bits uint32_t bits_len; // Note: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating // Constants for MD5 Transform const uint32_t k[] = { x428a2f98, x71374491, xb5cfbcf, xe9b5dba5, x3956c25b, x59f111f1, x923f82a4, xab1c5ed5, xd807aa98, x12835b01, x243185be, x550c7dc3, x72be5d74, x80deb1fe, x9bdc06a7, xc19bf174, xe49b69c1, xefbe4786, xfc19dc6, x240ca1cc, x2de92c6f, x4a7484aa, x5cba9dc, x76f988da, x983e5152, xa831c66d, xb00327c8, xbf597fc7, xc6e00bf3, xd5a79147, x06ca6351, x14292967, x27b70a85, x2e1b2138, x4d2c6dfc, x53380d13, x650a7354, x766aabb, x81c2c92e, x92722c85, xa2bfe8a1, xa81a664b, xc24b8b70, xc76c51a3, xd192e819, xd6990624, xf40e3585, x106aa070, x19a4c116, x1e376c08, x2748774c, x34bbcb5, x391ccb3, x4ed8aa4a, x5b9cca4f, x682e6ff3, x748f82ee, x78a5636f, x84c87814, x8cc70208, x90befffa, xa4506ceb, xbef9a3f7, xc67178f2 }; // Initialize variables - simple count in nibbles: // one nibble is half a byte, two nibbles is a byte. h = x67452301; h1 = xefcdab89; h2 = x98badcfe; h3 = x10325476; // Pre-processing: // append "1" bit to message // append "" bits until message length in bits ≡ 448 (mod 512) // append length mod (2^64) to message for (size_t i = ; i < initial_len; i++) { if (i % 64 == ) { msg = realloc(msg, (i / 64 + 1) * 64); } msg[i] = initial_msg[i]; } msg[initial_len] = 128; // append the "1" bit; most significant bit is "first" bits_len = initial_len * 8; // note, we append the len msg = realloc(msg, (bits_len / 512 + 1) * 512); // append "" bits memset(msg + initial_len + 1, , (bits_len / 512 + 1) * 512 - initial_len - 1); // set remaining bits to zero ((uint64_t *) msg)[bits_len / 64] = initial_len * 8; // append len in bits // Process the message in successive 512-bit chunks: // for each 512-bit chunk of message: for (size_t chunk = ; chunk < bits_len / 512 + 1; chunk++) { // break chunk into sixteen 32-bit words w[j], ≤ j ≤ 15 uint32_t *w = (uint32_t *) (msg + chunk * 512); // Initialize hash value for this chunk: uint32_t a = h; uint32_t b = h1; uint32_t c = h2; uint32_t d = h3; // Main loop: for (size_t i = ; i < 64; i++) { uint32_t f, g; if (i < 16) { f = (b & c) | ((~b) & d); g = i; } else if (i < 32) { f = (d & b) | ((~d) & c); g = (5 * i + 1) % 16; } else if (i < 48) { f = b ^ c ^ d; g = (3 * i + 5) % 16; } else { f = c ^ (b | (~d)); g = (7 * i) % 16; } uint32_t temp = d; d = c; c = b; b = b + LEFTROTATE((a + f + k[i] + w[g]), 7); a = temp; } // Add this chunk's hash to result so far: h += a; h1 += b; h2 += c; h3 += d; } // cleanup free(msg); // Produce the final hash value (big-endian): digest[] = (h >> 24) & xff; digest[1] = (h >> 16) & xff; digest[2] = (h >> 8) & xff; digest[3] = h & xff; digest[4] = (h1 >> 24) & xff; digest[5] = (h1 >> 16) & xff; digest[6] = (h1 >> 8) & xff; digest[7] = h1 & xff; digest[8] = (h2 >> 24) & xff; digest[9] = (h2 >> 16) & xff; digest[10] = (h2 >> 8) & xff; digest[11] = h2 & xff; digest[12] = (h3 >> 24) & xff; digest[13] = (h3 >> 16) & xff; digest[14] = (h3 >> 8) & xff; digest[15] = h3 & xff; } 注意:以上代码仅供参考,实际使用时需要根据具体情况进行修改和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值