如何用C ++语言实现动态代理? [英] How to realize dynamic proxy in C++ language?

查看:306
本文介绍了如何用C ++语言实现动态代理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对动态代理模式感到困惑,这是一种代理模式。

如何用C ++语言实现动态代理模式?

请给我举个例子关于C ++语言中的动态代理!

I am confused about dynamic proxy mode,which is a kind of proxy mode.
How to realize dynamic proxy mode in C++ language?
Please give me an example about dynamic proxy in C++ language!

推荐答案

看起来你运气不好 [ ^ ]。


首先看到上面的CPallini的简答题(nope);) />


答案很长。

代理是一种设计模式,可以让你为其他人提供一个界面通过创建包装类作为代理来创建对象。包装类(代理)可以在不更改对象代码的情况下向感兴趣的对象添加其他功能。



有两种代理:



- 静态代理(为每个类创建一个代理对象) )

- 动态代理(代理是通过反射动态创建的



C ++语言确实如此不支持反思为什么C ++没有反射?



First of all see the short answer (nope) of CPallini above ;)

The long answer comes here.
A proxy is a design pattern that allows you to provide an interface to other objects by creating a wrapper class as the proxy. The wrapper class, which is the proxy, can add additional functionality to the object of interest without changing the object's code.

There is two kinds of proxy:

- Static Proxy (create a proxy object for every class)
- Dynamic Proxy (proxies are created dynamically through reflection)

The C++ language does not support reflection: Why does C++ not have reflection?



C ++中有几个反射问题。



要添加很多工作,C ++委员会相当保守,除非他们确定能够获得回报,否则不要花时间研究激进的新功能。 (建议添加一个类似于.NET程序集的模块系统,虽然我认为普遍的共识是它很高兴,但它现在不是他们的首要任务,并且一直被推迟到C ++ 0x。此功能的动机是摆脱#include系统,但它也会启用至少一些元数据)。



你不喜欢支付你不使用的东西。这是C ++背后必须的基本设计理念之一。如果我可能永远不需要,我的代码为什么要携带元数据?此外,元数据的添加可能会阻止编译器进行优化。如果我可能永远不需要那些元数据,为什么我要在代码中支付这笔费用呢?



这引出了另一个重点:C ++对编译的代码几乎没有保证。只要产生的功能符合预期,编译器就可以做任何喜欢的事情。 例如,您的课程不需要实际存在。编译器可以优化它们,内联它们所做的一切,并且它经常这样做,因为即使是简单的模板代码也往往会创建相当多的模板实例。 C ++标准库依赖于这种积极的优化。如果可以优化实例化和破坏对象的开销,那么Functors只有性能。向量上的operator []仅与性能中的原始数组索引相当,因为整个运算符可以内联并因此完全从已编译的代码中删除。 C#和Java对编译器的输出做了很多保证。如果我在C#中定义一个类,那么该类将存在于生成的程序集中。即使我从不使用它。即使可以内联所有对其成员函数的调用。班级必须在那里,以便反思可以找到它。部分结果可以通过C#编译为字节码来缓解,这意味着JIT编译器可以删除类定义和内联函数(如果它喜欢),即使初始C#编译器不能。在C ++中,您只有一个编译器,它必须输出有效的代码。如果允许您检查C ++可执行文件的元数据,那么您希望看到它定义的每个类,这意味着编译器必须保留所有已定义的类,即使它们不是必需的。



然后有模板。 C ++中的模板与其他语言中的泛型不同。每个模板实例化都会创建一个新类型。的std ::矢量< INT>是一个与std :: vector< float>完全独立的类。这在整个程序中增加了许多不同的类型。我们的反思应该看到什么?模板std :: vector?但它怎么可能,因为这是一个源代码构造,在运行时没有意义?它必须看到单独的类std :: vector< int>和std :: vector< float>。和std :: vector< int> :: iterator和std :: vector< float> :: iterator,const_iterator相同,依此类推。一旦你进入模板元编程,你很快就会最终实例化数百个模板,所有模板都会被编译器内联并再次删除。它们没有任何意义,除非作为编译时元程序的一部分。所有这几百个课程都应该可以反映出来吗?他们必须这样做,因为否则我们的反思就会毫无用处,如果它甚至不能保证我定义的类实际上会在那里。另一个问题是模板类在实例化之前不存在。想象一下使用std :: vector< int>的程序。我们的反射系统应该能够看到std :: vector :: iterator吗?一方面,你当然希望如此。它是一个重要的类,它是根据std :: vector< int>定义的,它确实存在于元数据中。另一方面,如果程序从未实际使用此迭代器类模板,则其类型将永远不会被实例化,因此编译器将不会首先生成该类。而且在运行时创建它已经太晚了,因为它需要访问源代码。

最后,反射在C ++中并不像在C#中那样重要。原因是模板元编程。它无法解决所有问题,但是在许多情况下,除非您采用反射,否则可以编写一个在编译时执行相同操作的元程序。 boost :: type_traits是一个简单的例子。你想知道T型吗?检查其type_traits。在C#中,你必须使用反射在它的类型之后钓鱼。反射对于某些事情仍然有用(我可以看到的主要用途,哪个元编程不能轻易替换,用于自动生成的序列化代码),但它会为C ++带来一些重要的成本,并且它不需要像它一样频繁。是其他语言。




There are several problems with reflection in C++.

It's a lot of work to add, and the C++ committee is fairly conservative, and don't spend time on radical new features unless they're sure it'll pay off. (A suggestion for adding a module system similar to .NET assemblies has been made, and while I think there's general consensus that it'd be nice to have, it's not their top priority at the moment, and has been pushed back until well after C++0x. The motivation for this feature is to get rid of the #include system, but it would also enable at least some metadata).

You don't pay for what you don't use. That's one of the must basic design philosophies underlying C++. Why should my code carry around metadata if I may never need it? Moreover, the addition of metadata may inhibit the compiler from optimizing. Why should I pay that cost in my code if I may never need that metadata?

Which leads us to another big point: C++ makes very few guarantees about the compiled code. The compiler is allowed to do pretty much anything it likes, as long as the resulting functionality is what is expected. For example, your classes aren't required to actually be there. The compiler can optimize them away, inline everything they do, and it frequently does just that, because even simple template code tends to create quite a few template instantiations. The C++ standard library relies on this aggressive optimization. Functors are only performant if the overhead of instantiating and destructing the object can be optimized away. operator[] on a vector is only comparable to raw array indexing in performance because the entire operator can be inlined and thus removed entirely from the compiled code. C# and Java make a lot of guarantees about the output of the compiler. If I define a class in C#, then that class will exist in the resulting assembly. Even if I never use it. Even if all calls to its member functions could be inlined. The class has to be there, so that reflection can find it. Part of this is alleviated by C# compiling to bytecode, which means that the JIT compiler can remove class definitions and inline functions if it likes, even if the initial C# compiler can't. In C++, you only have one compiler, and it has to output efficient code. If you were allowed to inspect the metadata of a C++ executable, you'd expect to see every class it defined, which means that the compiler would have to preserve all the defined classes, even if they're not necessary.

And then there are templates. Templates in C++ are nothing like generics in other languages. Every template instantiation creates a new type. std::vector<int> is a completely separate class from std::vector<float>. That adds up to a lot of different types in a entire program. What should our reflection see? The template std::vector? But how can it, since that's a source-code construct, which has no meaning at runtime? It'd have to see the separate classes std::vector<int> and std::vector<float>. And std::vector<int>::iterator and std::vector<float>::iterator, same for const_iterator and so on. And once you step into template metaprogramming, you quickly end up instantiating hundreds of templates, all of which get inlined and removed again by the compiler. They have no meaning, except as part of a compile-time metaprogram. Should all these hundreds of classes be visible to reflection? They'd have to, because otherwise our reflection would be useless, if it doesn't even guarantee that the classes I defined will actually be there. And a side problem is that the template class doesn't exist until it is instantiated. Imagine a program which uses std::vector<int>. Should our reflection system be able to see std::vector::iterator? On one hand, you'd certainly expect so. It's an important class, and it's defined in terms of std::vector<int>, which does exist in the metadata. On the other hand, if the program never actually uses this iterator class template, its type will never have been instantiated, and so the compiler won't have generated the class in the first place. And it's too late to create it at runtime, since it requires access to the source code.
And finally, reflection isn't quite as vital in C++ as it is in C#. The reason is again, template metaprogramming. It can't solve everything, but for many cases where you'd otherwise resort to reflection, it's possible to write a metaprogram which does the same thing at compile-time. boost::type_traits is a simple example. You want to know about type T? Check its type_traits. In C#, you'd have to fish around after its type using reflection. Reflection would still be useful for some things (the main use I can see, which metaprogramming can't easily replace, is for autogenerated serialization code), but it would carry some significant costs for C++, and it's just not necessary as often as it is in other languages.


这篇关于如何用C ++语言实现动态代理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆