Variant拷贝与Object的相等判断

最近在调试代码时,发现代码中在进行赋值或相等判断时,不少直接采用赋值操作符=、相等判断==进行处理,但实际上,这样做是存在风险的。

Variant拷贝请使用VariantCopy或直接采用CComVariant的赋值运算符、Copy方法,慎用Variant的=操作符

#include <iostream>
#include<variant>
#include<OAIdl.h>
#include<mbstring.h>
#include <comdef.h>
#include <atlbase.h>

using namespace std;
CComVariant GetVariantFromVariant1()
{
CComVariant varNew;
CComVariant varOld;
VariantInit(&varNew);
VariantInit(&varOld);
varOld.vt = VT_BSTR;
varOld.bstrVal = ::SysAllocString(L"Welcome to China!\n");
string str = _com_util::ConvertBSTRToString(varOld.bstrVal);
std::cout << str;

VariantClear(&varNew);
varNew.Copy(&varOld) ; //CComVariant的Copy方法,实现CComVariant的拷贝

VariantClear(&varOld);
varOld.bstrVal = ::SysAllocString(L"Welcome to Hubei!\n");

return varNew;
}

CComVariant GetVariantFromVariant2()
{
CComVariant varNew;
CComVariant varOld;
VariantInit(&varNew);
VariantInit(&varOld);
varOld.vt = VT_BSTR;
varOld.bstrVal = ::SysAllocString(L"Welcome to China!\n");
string str = _com_util::ConvertBSTRToString(varOld.bstrVal);
std::cout << str;

VariantClear(&varNew);
varNew = varOld; //CComVariant的赋值运算符,实际是调用的::VariantCopy(this, const_cast<VARIANT*>(pSrc));

VariantClear(&varOld);
varOld.bstrVal = ::SysAllocString(L"Welcome to Hubei!\n");

return varNew;
}

VARIANT GetVariantFromVariant3()
{
VARIANT varNew;
VARIANT varOld;
VariantInit(&varNew);
VariantInit(&varOld);
varOld.vt = VT_BSTR;
varOld.bstrVal = ::SysAllocString(L"Welcome to China!\n");
string str = _com_util::ConvertBSTRToString(varOld.bstrVal);
std::cout << str;

VariantClear(&varNew);
varNew = varOld; //错误的Variant拷贝

VariantClear(&varOld);
varOld.bstrVal = ::SysAllocString(L"Welcome to Hubei!\n");

return varNew;
}

VARIANT GetVariantFromVariant4()
{
VARIANT varNew;
VARIANT varOld;
VariantInit(&varNew);
VariantInit(&varOld);
varOld.vt = VT_BSTR;
varOld.bstrVal = ::SysAllocString(L"Welcome to China!\n");
string str = _com_util::ConvertBSTRToString(varOld.bstrVal);
std::cout << str;

VariantCopy(&varNew, &varOld); //正确的Variant拷贝

VariantClear(&varOld);
varOld.bstrVal = ::SysAllocString(L"Welcome to Hubei!\n");

return varNew;
}

int main()
{
CComVariant var1 = GetVariantFromVariant1();
string str1 = _com_util::ConvertBSTRToString(var1.bstrVal);
std::cout << str1;

CComVariant var2 = GetVariantFromVariant2();
string str2 = _com_util::ConvertBSTRToString(var2.bstrVal);
std::cout << str2;

VARIANT var3 = GetVariantFromVariant3();
string str3 = _com_util::ConvertBSTRToString(var3.bstrVal);
std::cout << str3;

VARIANT var4 = GetVariantFromVariant4();
string str4 = _com_util::ConvertBSTRToString(var4.bstrVal);
std::cout << str4;
}

运行结果

 

Object的相等判断请使用Equals方法,慎用==

static void Main(string[] args)
{
Console.WriteLine("Hello World!\n");
string str1 = "Hello Hubei\n";
string str2 = "Hello Hubei\n";
object obj1 = str1;
object obj2 = str2;

Console.WriteLine(obj1 == obj2);//true
Console.WriteLine(obj1.Equals(obj2));//true

string strTemp3 = new string(new char[] { 'a', 'b', 'c', 'd' });
string strTemp4 = new string(new char[] { 'a', 'b', 'c', 'd' });

object obj3 = strTemp3;
object obj4 = strTemp4;

Console.WriteLine(obj3 == obj4); //false
Console.WriteLine(obj3.Equals(obj4));//true

}

运行结果

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Variant 是一种可以存储不同类型数据的数据类型。在 C++ 中可以使用模板实现 Variant ,具体实现如下: ```cpp #include <memory> #include <type_traits> class Variant { public: Variant() noexcept = default; Variant(const Variant& other) { if (other._data) { other._data->copy_to(_data); _type_info = other._type_info; } } Variant& operator=(const Variant& other) { if (other._data) { other._data->copy_to(_data); _type_info = other._type_info; } else { _data.reset(); _type_info = nullptr; } return *this; } template <typename T> Variant(T&& value) { _data = std::make_unique<Holder<std::decay_t<T>>>(std::forward<T>(value)); _type_info = &typeid(std::decay_t<T>); } template <typename T> Variant& operator=(T&& value) { if (_data) { _data.reset(); } _data = std::make_unique<Holder<std::decay_t<T>>>(std::forward<T>(value)); _type_info = &typeid(std::decay_t<T>); return *this; } template <typename T> const T& get() const { if (_type_info && *_type_info == typeid(T)) { return static_cast<Holder<T>*>(_data.get())->value; } throw std::bad_cast(); } template <typename T> T& get() { if (_type_info && *_type_info == typeid(T)) { return static_cast<Holder<T>*>(_data.get())->value; } throw std::bad_cast(); } bool empty() const { return !_data; } private: class IHolder { public: virtual ~IHolder() = default; virtual void copy_to(std::unique_ptr<IHolder>& other) const = 0; }; template <typename T> class Holder : public IHolder { public: template <typename U> Holder(U&& value) : value(std::forward<U>(value)) {} void copy_to(std::unique_ptr<IHolder>& other) const override { other = std::make_unique<Holder<T>>(value); } T value; }; std::unique_ptr<IHolder> _data; const std::type_info* _type_info = nullptr; }; ``` 该实现中,使用了一个 IHolder 抽象基类来表示存储的数据,Holder 类是 IHolder 的具体实现,包含了存储的数据和拷贝操作。在 Variant 中,使用一个 std::unique_ptr<IHolder> 类型的成员变量 _data 存储数据,_type_info 存储数据的类型信息。 实现中还包括了拷贝构造函数、拷贝赋值运算符,并且支持使用任何类型来构造 Variant ,使用 get() 方法来获取存储的数据,并且支持空 Variant
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值