测试传递给函数的void*是否是shared_ptr或unique_ptr
Testing if a void* passed into a function is either a shared_ptr or a unique_ptr
我正在为类创建一个函数,参数被声明为void*,但在函数中,我需要测试这个void*是否为shared_ptr或unique_ptr是否有方法测试这种类型的情况?
这是我到目前为止正在研究的;我的类是模板类型,不存储任何成员变量。它有一个默认构造函数,它也可以通过传递shared_ptr<Type>
或unique_ptr<Type>
来构造,它有多个allocate()
函数,它们做相同类型的工作。
#ifndef ALLOCATOR_H
#define ALLOCATOR_H
#include <memory>
#include <iostream>
template<class Type>
class Allocator {
public:
Allocator(){}
Allocator( Type type, void* pPtr );
Allocator( std::shared_ptr<Type>& pType );
Allocator( std::unique_ptr<Type>& pType );
// ~Allocator(); // Default Okay
void allocate( std::shared_ptr<Type>& pType );
void allocate( std::unique_ptr<Type>& pType );
void allocate( Type type, void* pPtr );
private:
Allocator( const Allocator& c ); // Not Implemented
Allocator& operator=( const Allocator& c ); // Not Implemented
}; // Allocator
#include "Allocator.inl"
#endif // ALLOCATOR_H
我的*.cpp
文件只有#include "Allocator.h"
,因为所有的实现都在我的*.inl
文件。
两个构造函数:Allocator( std::shared_ptr<Type>& pType );
&Allocator( std::unique_ptr<Type>& pType );
以及两个匹配的allocate()
函数工作良好。构造函数Allocator( Type type, void* pPtr );
及其匹配函数是我遇到麻烦的地方。
构造函数本身是直接的,因为它所做的只是调用匹配的函数,将变量传递给它。
template<class Type>
Allocator<Type>::Allocator( Type type, void* pPtr ) {
allocate( type, eType, pPtr );
}
这是在功能实现,我是挣扎。
template<class Type>
void Allocator<Type>::allocate( Type type, void* pData ) {
if ( pData == reinterpret_cast<void*>( std::shared_ptr<Type ) ) {
std::shared_ptr<Type> pShared;
pShared.reset( new Type( type ) );
pData = reinterpret_cast<void*>( pShared );
} else if ( pData == reinterpret_cast<void*>( std::unique_ptr<Type ) ) {
std::unique_ptr<Type> pUnique;
pUnique.reset( new Type( type ) );
pData = reinterpret_cast<void*>( pUnique );
} else {
std::cout << "Error invalid pointer type passed in << std::endl
<< "must be either a std::shared_ptr<Type> << std::endl
<< "or a std::unique_ptr<Type> << std::endl;
}
}
除了检查是否传入void*
是std::shared_ptr<Type>
或std::unique_ptr<Type>
的其他问题,我可能会有,是我使用reinterpret_cast<void*>
的正确方式将智能指针转换为void指针,如果不是如何实现?
你不能检查void*
是什么类型。这是void*
。就是这样。它不像boost::any
,它狡猾地隐藏了一些其他类型信息。就是 void*
。你不能检查它是什么类型的。你无法测试它是否来自一个特定的类型。你没有任何信息。邮政编码。没有什么结果。无价值之物。空白。
void*
指针不携带任何类型信息。您需要做的是与void*
一起传递一个附加值,以指定void*
指向的内容,然后您可以相应地对其进行类型转换。
#ifndef ALLOCATOR_H
#define ALLOCATOR_H
#include <memory>
#include <iostream>
template<class Type>
class Allocator {
public:
enum AllocateType { eSharedPtr, eUniquePtr };
Allocator() {}
Allocator( Type type, std::shared_ptr<Type>& pData );
Allocator( Type type, std::unique_ptr<Type>& pData );
// ~Allocator(); // Default Okay
void allocate( Type type, std::shared_ptr<Type>& pData );
void allocate( Type type, std::unique_ptr<Type>& pData );
private:
Allocator( const Allocator& c ); // Not Implemented
Allocator& operator=( const Allocator& c ); // Not Implemented
void allocate( Type type, AllocateType eDataType, void* pData );
}; // Allocator
#include "Allocator.inl"
#endif // ALLOCATOR_H
template<class Type>
Allocator<Type>::Allocator( Type type, std::shared_ptr<Type>& pData ) {
allocate( type, pData );
}
template<class Type>
Allocator<Type>::Allocator( Type type, std::unique_ptr<Type>& pData ) {
allocate( type, pData );
}
template<class Type>
void Allocator<Type>::allocate( Type type, std::shared_ptr<Type>& pData ) {
allocate( type, eSharedPtr, &pData );
}
template<class Type>
void Allocator<Type>::allocate( Type type, std::unique_ptr<Type>& pData ) {
allocate( type, eUniquePtr, &pData );
}
template<class Type>
void Allocator<Type>::allocate( Type type, AllocateType eDataType, void* pData ) {
switch (eDataType) {
case eSharedPtr: {
static_cast<std::shared<Type>*>(pData)->reset( new Type( type ) );
break;
}
case eUniquePtr: {
static_cast<std::unique_ptr<Type>*>(pData)->reset( new Type( type ) );
break;
}
}
}
在这种情况下,我甚至不会费心尝试将所有内容都汇集到一个函数中,以
开头:#ifndef ALLOCATOR_H
#define ALLOCATOR_H
#include <memory>
#include <iostream>
template<class Type>
class Allocator {
public:
Allocator() {}
Allocator( Type type, std::shared_ptr<Type>& pData );
Allocator( Type type, std::unique_ptr<Type>& pData );
// ~Allocator(); // Default Okay
void allocate( Type type, std::shared_ptr<Type>& pData );
void allocate( Type type, std::unique_ptr<Type>& pData );
private:
Allocator( const Allocator& c ); // Not Implemented
Allocator& operator=( const Allocator& c ); // Not Implemented
}; // Allocator
#include "Allocator.inl"
#endif // ALLOCATOR_H
template<class Type>
Allocator<Type>::Allocator( Type type, std::shared_ptr<Type>& pData ) {
allocate( type, pData );
}
template<class Type>
Allocator<Type>::Allocator( Type type, std::unique_ptr<Type>& pData ) {
allocate( type, pData );
}
template<class Type>
void Allocator<Type>::allocate( Type type, std::shared_ptr<Type>& pData ) {
pData.reset( new Type( type ) ) ;
}
template<class Type>
void Allocator<Type>::allocate( Type type, std::unique_ptr<Type>& pData ) {
pData.reset( new Type( type ) );
}
经过一番考虑,并且知道这个类并不在内部存储任何成员变量,只包含执行特定任务的函数后,我采用了一种不同的方法。我非常感谢每个人的反馈和回答,因为他们确实对我最初提出的基本问题给出了很好的有效答案。这是我从你的建议中得到的。我去掉了这个类本身是模板的规定,将默认构造函数设为private。我确保每个函数都是一个函数模板,并使它们成为静态的。这是我的新类:
Allocator.h
#ifndef ALLOCATOR_H
#define ALLOCATOR_H
#include <memory>
class Allocator {
public:
template<class Type>
inline static void allocate( std::shared_ptr<Type>& pShared, const Type& type = Type() );
template<class Type>
inline static void allocate( std::unique_ptr<Type>& pUnique, const Type& type = Type() );
private:
Allocator();
Allocator( const Allocator& c );
Allocator& operator=( const Allocator& c );
}; // Allocator
#include "Allocator.inl"
#endif // Allocator
Allocator.cpp
#include "Allocator.h"
Allocator.inl
template<class Type>
inline void Allocator::allocate( std::shared_ptr<Type>& pShared, const Type& type ) {
pShared.reset( new Type( type ) );
}
template<class Type>
inline void Allocator::allocate( std::unique_ptr<Type>& pUnique, const Type& type ) {
pUnique.reset( new Type( type ) );
}
这使得使用该类变得简单。
main.cpp
#include <iostream>
#include <conio.h>
#include "Allocator.h"
class A {
private:
int m_a;
public:
explicit A( int a = 0 ) : m_a( a ) {}
A( const A& a ) { this->m_a = a.m_a; }
int getA() const { return m_a; }
void setA( int a ) { m_a = a; }
}; // A
int main() {
// Creating Smart A Pointer Just From A Class Type
std::shared_ptr<A> pShared;
std::unique_ptr<A> pUnique;
Allocator::allocate( pShared );
Allocator::allocate( pUnique );
std::cout << "Shared: " << pSharedA->getA() << std::endl;
std::cout << "Unique: " << pUniqueA->getA() << std::endl;
pSharedA->setA( 4 );
pUniqueA->setA( 5 );
std::cout << "Shared: " << pSharedA->getA() << std::endl;
std::cout << "Unique: " << pUniqueA->getA() << std::endl;
// Create A Smart Pointer From An Object Of Type In This Case A
// This next sections does rely on the fact that Type in this case A, should have a copy constructor defined.
A a1( 3 );
std::shared_ptr<A> sharedA;
std::unique_ptr<A> uniqueA;
Allocator::allocate( sharedA, a1 );
Allocator::allocate( uniqueA, a1 );
std::cout << "Shared: " << sharedA->getA() << std::endl;
std::cout << "Unique: " << uniqueA->getA() << std::endl;
sharedA->setA( 6 );
uniqueA->setA( 7 );
std::cout << "Shared: " << sharedA->getA() << std::endl;
std::cout << "Unique: " << uniqueA->getA() << std::endl;
pSharedA.reset();
pUniqueA.release();
pUniqueA.reset();
sharedA.reset();
uniqueA.release();
uniqueA.reset();
std::cout << std::endl << "Press Any Key To Quit" << std::endl;
_getch();
return 0;
} // main
这也消除了做任何类型转换、比较等的需要,提高了所做工作的效率。我甚至可以更进一步,将所有这些函数声明为内联。
编辑
我采纳了Remy Lebeau的建议,通过添加Type type
作为默认形参删除了两个重载函数,并将其更改为通过const引用传递。
- C++LDAP检查用户是否是特定组的成员
- 检查某些类型是否是模板类 std::optional 的实例化
- 将错误返回给调用方而不是立即在 C++ 中抛出错误是否是一种好的做法
- 如何检查模板专用化是否是基本模板的子类?
- 如何检查变量是否是C++中的地图?
- C++ Chrono 确定一天是否是周末?
- 将相同共享指针的副本存储在不同的向量中是否是一种好的做法?
- 使用类在C++中存储和列出变量/方法是否是一种好的做法
- 代码在 CodeSignal 中工作不正确。不确定这是否是我的代码缺陷
- 如果 C 函数仍然可以间接执行(通过回调函数),那么将它声明为静态函数是否是一种不好的做法?
- MFC 中的窗口消息管理:添加基类调用是否是强制性的?
- 检查 n2 是否是 n1 的倍数后结果错误,但根本没有错误
- C ++:检查它是否是类中的数字
- 传递给放置 new 的指针是否是指向其对象表示形式的非 UB 指针?
- 使用 SET(C++) 检查两个给定字符串是否是字谜时出现运行时错误
- 从 std::string 到 std::array<char,size> 的 memcopy 额外数据是否是一种未定义的行为?
- 有没有办法检查发送到变量的值是否是正确的类型,而它已经在该变量下?
- 如何检查一个模板是否是另一个模板的类成员
- 有没有办法检查用户输入是否是数字?
- 如何知道文本文件中的输入是否是 C++ 中的有效数字