前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >谨慎在对外提供的方法中使用inline

谨慎在对外提供的方法中使用inline

作者头像
gaigai
发布2021-01-21 09:56:24
3740
发布2021-01-21 09:56:24
举报
文章被收录于专栏:Windows开发Windows开发Windows开发

假设模块A对外提供一个类CPerson

class CPerson
{
public:
std::string m_strName;
int m_nAge = 0;
};

类CPerson定义三个字段:名字、年龄。

假设模块B集成模块A的能力,模块A内部和模块B都会使用类CPerson,那么会存在什么问题呢?

类CPerson的名字字段是使用std::string,std::string的定义和实现跟运行时库有关,vs2013和vs2017的运行时库可能是不一样的。如果模块A使用vs2017开发,而模块B使用vs2013开发,类Person对模块A和模块B来说是不一样的,必然会出现各种问题,甚至崩溃。那怎么办呢?

屏蔽CPerson内部的结构,对外导出方法。

class CPerson
{
public:
const char* GetName() { return m_strName.c_str(); }
void SetName(const char* name) { m_strName = name; }
int GetAge() { return m_nAge; }
    void SetAge(int nAge) { m_nAge = nAge; }
private:
std::string m_strName;
int m_nAge = 0;
};

对外导出的方法使用的int、const char*属于基本类型,与运行时库无关,解决了对运行时库的依赖,那还有其它隐患吗?

有,虽然导出的方法的实现都是在模块A内部,对内部字段的读写完全是由模块A实现,但是实例化CPerson对象的时候,给CPerson对象分配空间的大小sizeof(CPerson)跟CPerson内部字段的定义还是有关,假设模块B使用vs2013开发分配的CPerson对象的大小,比模块A使用vs2017开发分配的CPerson对象的大小来得小,就会导致调用SetAge()方法时越界内存破坏。那怎么办?

强烈建议不要在对外的类中使用std::string,std::vector等与运行时库相关的类。如果一定要用,那就另外提供CPerson类的创建/释放接口。

假设为了提升对CPerson的访问性能,于是在对外导出的方法中加上关键字inline,会有什么问题?

class CPerson
{
public:
inline const char* GetName() { return m_strName.c_str(); }
inline void SetName(const char* name) { m_strName = name; }
inline int GetAge() { return m_nAge; }
inline void SetAge(int nAge) { m_nAge = nAge; }
private:
std::string m_strName;
int m_nAge = 0;
};

关键字inline会使得对外方法的实现代码直接编译进调用模块B内,等于将CPerson内部的字段细节暴露给使用者,跟直接将字段定义成public没有区别,也会导致模块A和模块B在使用不同的运行时库时存在问题。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Windows开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档