gpt4 book ai didi

C++:将类传递给 vararg 函数

转载 作者:太空狗 更新时间:2023-10-29 21:25:10 24 4
gpt4 key购买 nike

我正在尝试创建一个行为类似于 MS CString 的类(也就是说,您将它传递给 printf,它就像一个指向 C 字符串的指针,没有像“.c_str()”这样的额外丑陋黑魔法)。

这是这个类的第一个实现,它可以正常工作,但还没有提供任何有用的东西:

#include <cstdlib>
#include <cstring>

class CString
{
protected:
struct CStringInfo
{
size_t Length;
size_t MaxLength;
};

public:
CString()
{
Buffer = NULL;

Assign(NULL);
}

CString(const char* chv)
{
Buffer = NULL;

Assign(chv, 0);
}

~CString()
{
if(Buffer) delete[] Buffer;
Buffer = NULL;
}

size_t GetLength()
{
if(!Buffer) Alloc(1);
return GetInfo()->Length;
}

size_t Resize(size_t size)
{
Alloc(size + 1); // + 0x00
Buffer[size] = 0;
return size;
}

bool Assign(const char* value, size_t size = 0)
{
size_t strl = ((size) ? size : strlen(value));

if(!value || !(strl = strlen(value)))
{
if(!Buffer) Alloc(1);
return false;
}

Alloc(strl + 1);
memcpy(Buffer, value, strl);
Buffer[strl] = 0;
return true;
}

CString& operator = (const char* what)
{
Assign(what);
return (*this);
}

CString& operator = (CString& string)
{
Assign(string.Buffer);
return (*this);
}

operator const char* ()
{
return Buffer;
}

protected:
char* Buffer;

void Alloc(size_t size)
{
if(!size) size = 1;
char* nb = new char[size + sizeof(CStringInfo)];
char* nbb = nb + sizeof(CStringInfo);
size_t cl = size - 1;
if(Buffer)
{
if(cl > GetInfo()->Length) cl = GetInfo()->Length;
if(cl) memcpy(nbb, Buffer, cl - 1);
nbb[cl] = 0;
*(CStringInfo*)(nb) = *(CStringInfo*)(Buffer);
delete[] (Buffer - sizeof(CStringInfo));
}

Buffer = nb;
GetInfo()->MaxLength = size;
GetInfo()->Length = cl;
}

void Free()
{
if(Buffer)
{
delete[] (Buffer - sizeof(CStringInfo));
}
}

CStringInfo* GetInfo()
{
return (CStringInfo*)(this->Buffer - sizeof(CStringInfo));
}
};

我测试它的代码:

#include <cstdio>
#include "CString.hpp"

CString global_str = "global string!";

int main(int argc, char* argv[])
{
CString str = "string";
printf("Test: %s, %s\n", str, global_str);
return 0;
}

如果我在类中没有析构函数,那么我可以将它传递给 printf,它将正常工作(作为 C 字符串)。但是当我添加析构函数时,GCC 会产生以下错误:

error: cannot pass objects of non-trivially-copyable type 'class CString' through '...'

除此之外,GCC 的早期版本还会给出警告 + ud2 操作码。

所以...问题:我真的可以在 GCC 中进行以下构造工作吗?或者是否有任何方法(可能不涉及 C 可变参数)来制作与上述代码相同的东西?

最佳答案

您可以通过强制转换触发转换运算符:

printf("Test: %s, %s\n", static_cast<const char*>(str), 
static_cast<const char*>(global_str));

但是,我不知道您是否会遇到任何问题,避免在 C++ 代码中使用可变参数可能是最好的。

如何使用 type-safe printf相反(来源:维基百科):

void printf(const char *s)
{
while (*s) {
if (*s == '%') {
if (*(s + 1) == '%') {
++s;
}
else {
throw std::runtime_error("invalid format string: missing arguments");
}
}
std::cout << *s++;
}
}

template<typename T, typename... Args>
void printf(const char *s, T value, Args... args)
{
while (*s) {
if (*s == '%') {
if (*(s + 1) == '%') {
++s;
}
else {
std::cout << value;
printf(s + 1, args...); // call even when *s == 0 to detect extra arguments
return;
}
}
std::cout << *s++;
}
throw std::logic_error("extra arguments provided to printf");
}

我认为 libstdc++ 不支持 std::runtime_errorstd::logic_error

关于C++:将类传递给 vararg 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14432539/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com