Effective C++: Item 41 -- Understand implicit interfaces and compile time polymorphism.

Definition

The world of object-oriented programming revolves around explicit interfaces and runtime polymorphism. In the world of templates and generic programming, explicit interfaces and runtime polymorphism continue to exist, but they’re less important. Instead, implicit interfaces and compile-time polymorphism move to the fore.

Terms Definition

OOP Example:
	class Widget { 
	public:
		Widget( );
		virtual ~Widget();
		virtual std::size_t size() const; 
		virtual void normalize();
		void swap(Widget& other);
		... 
	};
	void doProcessing(Widget& w) {
		if (w.size() > 10 && w != someNastyWidget) { 
			Widget temp(w);
			temp.normalize( );
			temp.swap(w);
		} 
	}
  • Explicit Interface: We can look up this interface in the source code (e.g., the .h file for Widget) to see exactly what it looks like.

  • Runtime Polymorphism : some of Widget’s member functions are virtual, w’s calls to those functions will exhibit runtime polymorphism: the specific function to call will be determined at runtime based on w’s dynamic type

Templates and generic programming example:
template<typename T> void doProcessing(T& w) {
	if (w.size() > 10 && w != someNastyWidget) { 
		T temp(w);
		temp.normalize( );
		temp.swap(w);
	} 
}
  • Implicit Interfaces: The interface that w must support is determined by the operations performed on w in the template. In this example, it appears that w’s type (T) must support the size, normalize, and swap member functions; copy construction (to create temp); and comparison for inequality (for comparison with someNastyWidget). The set of expressions that must be valid in order for the template to compile is the implicit interface that T must support. In other words, the operation that T must support for the template to compile is the implicit interface of T.
  • Compile-time Polymorphism: Because instantiating function templates with different template parameters leads to different functions being called, this is known as compile-time polymorphism. In other words, the function that being called according to template parameters is determined in compile time therefore it is called compile-time polymorphism.

Difference

Compile time polymorphism vs. runtime polymorphism

The difference between runtime and compile-time polymorphism is similar to the difference between the process of determining which of a set of overloaded functions should be called (which takes place during compilation) and dynamic binding of virtual function calls (which takes place at runtime).

Explicit vs. implicit interfaces

An explicit interface typically consists of function signatures, i.e., function names, parameter types, return types, etc.
An implicit interface is quite different. It consists of valid expressions.

template<typename T> void doProcessing(T& w) {
	if (w.size() > 10 && w != someNastyWidget) { 
		...
	}
}

The implicit interface for T (w’s type) appears to have these constraints:

  • It must offer a member function named size that returns an integral value.
  • It must support an operator!= function that compares two objects of type T. (Here, we assume that someNastyWidget is of type T.)

Note: Neither of the above need to be satisfy because of the operator overloading.
For example, the size function do not need to return an integral value. All it needs to do is return an object of some type X such that there is an operator> that can be called with an object of type X and an int (because 10 is of type int).
In other word, as long as the expressions are valid (i.e. code can compile without error), it is up to the developer to interpret the design of the implicit interface.

The expressions themselves may look complicated, but the constraints they impose are generally straightforward.
For example, if (w.size() > 10 && w != someNastyWidget) ... it’s hard to say much about the constraints on the functions size, oper- ator>, operator&&, or operator!=, but it’s easy to identify the constraint on the expression as a whole. The conditional part of an if statement must be a boolean expression.

Conclusion

Just as you can’t use an object in a way contradictory to the explicit interface its class offers (the code won’t compile), you can’t try to use an object in a template unless that object supports the implicit interface the template requires (again, the code won’t compile).

Things to Remember

  • Both classes and templates support interfaces and polymorphism.
  • For classes, interfaces are explicit and centered on function signatures. Polymorphism occurs at runtime through virtual functions.
  • For template parameters, interfaces are implicit and based on valid expressions. Polymorphism occurs during compilation through tem- plate instantiation and function overloading resolution.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
移植curl但是zlib无法使能,如何解决该问题 Host setup: arm-unknown-linux-gnueabihf Install prefix: /opt/rootfs/curl-7.79.0/curl-7.79.0/_install Compiler: arm-linux-gnueabihf-gcc CFLAGS: -Werror-implicit-function-declaration -O2 -Wno-system-headers -pthread CPPFLAGS: -isystem /opt/rootfs/openssl-1.1.1/openssl-1.1.1/_install/include LDFLAGS: -L/opt/rootfs/openssl-1.1.1/openssl-1.1.1/_install/lib LIBS: -lssl -lcrypto -ldl -lpthread curl version: 7.79.0 SSL: enabled (OpenSSL) SSH: no (--with-{libssh,libssh2}) zlib: no (--with-zlib) brotli: no (--with-brotli) zstd: no (--with-zstd) GSS-API: no (--with-gssapi) GSASL: no (libgsasl not found) TLS-SRP: enabled resolver: POSIX threaded IPv6: enabled Unix sockets: enabled IDN: no (--with-{libidn2,winidn}) Build libcurl: Shared=yes, Static=yes Built-in manual: enabled --libcurl option: enabled (--disable-libcurl-option) Verbose errors: enabled (--disable-verbose) Code coverage: disabled SSPI: no (--enable-sspi) ca cert bundle: no ca cert path: no ca fallback: no LDAP: no (--enable-ldap / --with-ldap-lib / --with-lber-lib) LDAPS: no (--enable-ldaps) RTSP: enabled RTMP: no (--with-librtmp) PSL: no (libpsl not found) Alt-svc: enabled (--disable-alt-svc) HSTS: enabled (--disable-hsts) HTTP1: enabled (internal) HTTP2: no (--with-nghttp2, --with-hyper) HTTP3: no (--with-ngtcp2, --with-quiche) ECH: no (--enable-ech) Protocols: DICT FILE FTP FTPS GOPHER GOPHERS HTTP HTTPS IMAP IMAPS MQTT POP3 POP3S RTSP SMB SMBS SMTP SMTPS TELNET TFTP Features: AsynchDNS HSTS HTTPS-proxy IPv6 Largefile NTLM NTLM_WB SSL TLS-SRP UnixSockets alt-svc
最新发布
06-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值