如何在c++运行时声明n阶指针
How to declare n-th order pointers in runtime in C++
指针可以这样声明:
int
a = 1,
*b = &a, // 1st order pointer
**c = &b, // 2nd order pointer
***d = &c, // 3rd order pointer
****e = &d, // 4th order pointer
*****f = &e, // 5th order pointer
*** n-stars *** f; // n-th order pointer
这里,在声明指针时,需要在编译时知道指针的顺序。是否有可能声明一个指针,其顺序只在运行时知道?链接到这个问题是是否有可能在运行时查询任意指针的顺序?
int order = GET_ORDER_OF_PTR(f) // returns 5
int /* insert some syntax here to make ptr a pointer of order (order + 1) */ ptr = &f;
注意:我已经知道这(通常)可能不是一个好主意。还是想知道它是否可行:)
在运行时你不能——因为c++是静态类型的。在编译过程中,可以使用模板,例如
template<typename T, int order> struct P
{
typedef typename P<T, order-1>::pointer* pointer;
};
template<typename T> struct P<T, 0>
{
typedef T pointer;
};
则P<int, 3>::pointer
等价于int***
你不能。c++是静态类型的,所以指针的顺序(这是其类型的一部分)必须在编译时知道。
不能在C或c++中使用,因为它们是静态类型语言(即存储在变量中的值的类型在编译时是已知的并且是固定的)。
您可以通过定义一个c++类 来模拟这种可能性。template<typename T>
struct NPtr {
int order;
void *p; // order 0 -> T*, otherwise NPtr<T>*
NPtr(NPtr *ptr) : islast(ptr->order+1), p(ptr) {}
NPtr(T *final) : islast(0), ptr(final) {}
NPtr<T>& nptr() {
assert(order > 0);
return *(NPtr<T>*)p;
}
T& final() {
assert(order == 0);
return *(T*)p;
}
};
TPtr<int>
实例可以是指向整数的指针(当order=0时),也可以是指向另一个TPtr<int>
实例的指针。
您想要的语义等效是一个链表,在运行时确定节点数量:
#include <iostream>
union kind_of_pointer
{
int data;
kind_of_pointer *next;
kind_of_pointer(int val) : data(val) {}
kind_of_pointer(kind_of_pointer* ptr) : next(ptr) {}
operator int()
{
return data;
}
kind_of_pointer& operator *()
{
return *next;
}
};
int main(void)
{
kind_of_pointer dyn_ptr{new kind_of_pointer{new kind_of_pointer{new kind_of_pointer{42}}}};
int*** static_ptr = new int**{new int *{new int{42}}};
std::cout << ***dyn_ptr << std::endl;
std::cout << ***static_ptr << std::endl;
}
我觉得这很有趣,很有趣,也很可怕。
你可以这样做:
int *f = nullptr;
decltype(f) *newptr = 0;
至于
是否可以在运行时查询任意序列的顺序指针?
部分:不,你绝对不能,除非你编写自己的包装器类来存储指针的顺序。指针基本上是一个数字:内存中的地址。
这给了你至少一个问题:你不能跟随指针"所有的方式"(你必须做的是检查你的指针指向的东西本身是一个指针),而没有潜在地导致段错误或读取"不是你的应用程序的内存"(这通常被操作系统禁止,并将导致你的应用程序被中止;不确定你是否能阻止这种情况)。
例如,可以将NULL(或0)强制转换为任何指针类型,因此它本身就是一个指针。但是它指向另一个指针吗?让我们来看看……砰!段错误。
哦,等等,还有另一个问题:您可以(使用c风格的强制转换或reinterpret_cast)将任何类型的指针强制转换为任何其他类型的指针。例如,a
可能指向一个指针,但被强制转换为不同的类型。或者a
可能有一个"指向指针"的类型,但实际上并没有指向指针。
注:很抱歉,动词"point"用得太随意了。
…在编译时声明指针时,需要知道指针的顺序。
是的,可以在编译时确定声明的指针类型的顺序;基于类型(可能通过typedef
)或变量,如果c++ 11可以使用(通过decltype()
)
#include <iostream>
using namespace std;
template <typename P>
struct ptr_order
{
static const int order = 0;
};
template <typename P>
struct ptr_order<P*>
{
static const int order = ptr_order<P>::order + 1;
};
int main()
{
typedef int*** pointer;
cout << ptr_order<pointer>::order << endl; // outputs 3
// could also use decltype if available...
// int*** p;
// ptr_order<decltype(p)>::order is also 3
}
运行时计算指针的顺序是不可能的,因为c++是静态类型的。
- 类的静态结构指针声明在C++
- 函数指针声明
- 指针声明
- 使用无效指针初始化指针声明符的行为是否未定义?
- 如何将指针声明以在类初始化器中的成员功能并拨打这些指针
- 指针声明和间接寻址之间的区别
- 是否可以将“自动”关键字用作函数指针声明中使用初始化的返回类型
- 与使用指针声明的字符串和C 中的数组相混淆
- 如何在C 中使用不同数据类型的类模板指针声明指针
- 指向STD :: vector,指针声明
- 为什么我们不能泛化指针声明?
- C 返回类型指针声明
- 将结构指针声明为函数的返回类型
- C++ h 和 cpp 文件中的指针声明冲突
- 为什么或何时用指针声明int
- 如何将函数指针声明指向模板函数,其返回类型取决于模板类
- 如何将方法指针声明为Typedef方法参数
- 通过参考或指针声明属性C
- C 指针声明
- 指针声明基础(多维数组指针的赋值)