第一次提问者:)是否有可能在不破坏代码的情况下将全局c样式数组转换为std :: arrays?我正在开发一个项目,其中包括反编译旧游戏的源代码.我们已经设法重构了反汇编/反编译输出的大部分内容.因为它是自动的,所以仍然有像
int a;
int b[50];
*(&a + 100) = xxx;
Run Code Online (Sandbox Code Playgroud)
要么
int b[50];
int a;
*(&a - 100) = xxx;
Run Code Online (Sandbox Code Playgroud)
还有其他类型的疯狂指针算术,它们尚未手动重构.但我们想使用边界检查已经(可能)正确更改为数组的部分.
(忽略斜体文本,我只是为了保持评论的一致性)到目前为止,我发现每个数组都有一个问题:sizeof(class containing array)会改变.这可能会在某些周期中破坏代码,例如someclass somearray [100]; //例如(sizeof(somearray [0])== 50)是真的int指针=(int)somearray; 指针+ = 100((someclass)指针) - > doSomething(); .因为pointer +=100不是指向第二个元素,而是指向第一个元素,或者甚至是第0个元素,我不确定(不要忘记它是自动反编译的代码,因此是丑陋的).
我正在考虑将每个全局数组更改为std :: array以及在没有[]运算符的情况下访问数组的每个实例array._Elems.
如果我要在这样的代码中将全局数组更改为std :: arrays,是否会出现任何问题?
编辑 你是对的,大小不变.我在测试功能中出错了.所以我会扩展这个问题:
将每个c样式数组更改为std :: array是否安全?
编辑 我们当前的代码实际上只能在调试模式下运行,因为它不会移动变量.发布模式基本上在程序开始时崩溃.
编辑 因为这个问题似乎有些混乱,让我澄清一下:除了T elems [N]之外,是否有一些保证阵列中没有其他成员?我能指望拥有
array<array<int,10>, 10> varname;
int* ptr = &varname[0][0];
ptr += 10
Run Code Online (Sandbox Code Playgroud)
varname[1][0] …
如标题所述,为什么这可能?通常模板化的函数如果不在输入参数中并且未明确说明,则无法确定它们的返回类型.例如:
class Foo {
public:
template<typename T>
operator T() { return T(); }
};
int main() {
Foo instance;
int someInteger = instance;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译并运行没有任何问题,即使返回类型未在任何地方明确说明.用户定义的转换运算符在模板规则方面是否有些特殊?
我意识到它在语法上不是返回类型.尽管如此,它在语义上是.毕竟,它是运算符返回的对象类型.
编辑:问题应该是"为什么模板化函数不能确定它们的返回类型?" 这是无效的:
template <class T>
T sizeGetterFun()
{
return std::numeric_limits<T>::max();
}
int main() {
int maxInt = sizeGetterFun();
double maxDouble = sizeGetterFun();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是有效的,并且与无效代码请求的内容相同.
class Foo {
public:
template<typename T>
operator T()
{
return std::numeric_limits<T>::max();
}
};
Foo sizeGetterFun()
{
return Foo();
}
int main() {
int maxInt = sizeGetterFun(); …Run Code Online (Sandbox Code Playgroud) 我正在使用以下模式处理包含多个函数的代码
memberType* var = NULL;
switch(someVariable)
{
case 0: var = &object.MemberVariable1; break;
case 1: var = &object.MemberVariable2; break;
case 2: var = &object.MemberVariable3; break;
}
Run Code Online (Sandbox Code Playgroud)
成员变量属于同一类型.在一些开关中有几十个案例,它们使功能体与基本上只是数据相混淆.我想创建一个数组,地图或类似的东西,以便我可以根据输入值访问成员.
我想要有类似的东西
sometype array[size] = {member1, member2, member3}
Run Code Online (Sandbox Code Playgroud)
所以功能可以包含
memberType* var = array[index];
Run Code Online (Sandbox Code Playgroud)
而不是开关.
1. 我的第一个想法是在类中创建一个包含单个成员变量和数组的联合,因此我可以访问各个成员或通过array + index访问它们.这是丑陋的,乍一看代码并不明显,并迫使成员变量以连续的方式声明.它也不允许我为不同的索引访问相同的成员变量.
2. 拥有一个包含返回单个成员变量的函数的函数指针的数组迫使我创建大量的一行getter函数.
3. 有一个静态分配的对象,所以我可以做类似的事情
int offsets[size] = {
*(int*)&staticObject.member1 - *(int*)&staticObject,
*(int*)&staticObject.member2 - *(int*)&staticObject,
*(int*)&staticObject.member3 - *(int*)&staticObject}
Run Code Online (Sandbox Code Playgroud)
并使用它
var = (memberType*)(*(int*)&object + offsets[index]);
Run Code Online (Sandbox Code Playgroud)
真可怕
有没有一种很好的方法可以摆脱这种不必要的冗长模式?
免责声明:我没有测试示例中使用的代码.这只是为了说明.
编辑:我忘了提到一件重要的事情:我不想因为序列化而改变类的大小 - 我还没有理解我正在使用的实现.
我正在嵌入式系统上编写应用程序.我需要某种类型的关联容器才能根据字符串访问某个指针.目前我正在使用地图(即 std::map<char*, SomeType*, CustomComparator>).我使用char*作为键类型,因为我正在与其他必须支持std :: string的库进行通信,而且我不想继续来回转换.
但我遇到了一个意想不到的问题.std :: map的每个实例(即新类型)在生成的二进制文件中占用大约10Kb(没有优化,用于调试目的).由于我限制了大约500Kb的ROM并且我可能需要几十个,这是一个非常显着的缺点(我想在实际硬件上进行调试,如果程序不适合我不能) .如果可能的话,我希望能够以对数时间访问这些项目.我不想求助于使用数组并循环遍历每个项目,直到找到我正在寻找的那个.插入不必很快,因为这只是在启动时完成的.删除仅在关闭期间执行,因此它们也不是问题.
有没有人有我可以使用的替代想法(最好是STL)?
注意:我仅限于C++ 03.
c++ ×4
arrays ×1
c++03 ×1
c++11 ×1
coding-style ×1
containers ×1
disassembly ×1
embedded ×1
readability ×1
stdarray ×1
stl ×1
templates ×1