如何在优雅的对象中包装 C 样式数组?
How to wrap a C style array in an Elegant Object?
我在 C++98 中使用一个使用 C 风格数组的库。
我想隐藏所有这些并通过声明代码简单地与之交互。
我正在寻找类似这个伪代码的东西。
智能指针是一个挑战。
我可以使用 boost 1.61 的 boost 智能指针
https://www.boost.org/doc/libs/1_61_0/libs/smart_ptr/smart_ptr.htm
class ElegantArray
{
private:
char* array; // <<<==== should be a unique or auto ptr?
int size;
std::string aString;
public:
ElegantArray(char* array_, int size_) { // <<<=============should require a smart pointer
array = array_;
size = size_; //<<<===constructor leaves aString nil which requires nil checks =(
}
ElegantArray(std::string aString_) {
aString = aString_; // <<<===constructor leaves array and size nil which requires nil checks =(
}
std::string string() {
int i; //put inside for loop?
std::string strng = "";
for (i = 0; i < size; i++) { strng = strng + array[i]; }
return strng;
}
//How & What do i return here unique or auto ptr?
char* cArrayPointer() {
int n = aString.length();
char charArray[n+1];
strcpy(charArray, aString.c_str());
return charArray; // <<<==================should return a smart pointer
}
}
调用站点类似于
ElegantArray elegantArray(smartPointerToCArray, arraySize);
std::string aString = elegantArray.string();
和
ElegantArray elegantArray("Falalalala");
SmartPointerToCArray smartPointerToCArray = elegantArray.cArrayPointer();
请指教
我猜你说的是 char
的 c 数组。在这种情况下,您正在寻找 std::string
:
#include <string>
#include <iostream>
int main() {
typedef std::string ElegantArray;
char x[] = "Foo";
const char* y = "Bar";
ElegantArray a(x);
ElegantArray b(y);
ElegantArray c("Baz");
std::cout << a << " " << b << " " << c;
}
如果您需要 c 字符串,请使用 std::string::c_str()
。
我假设您正在使用处理 char *
的 API;需要与处理 std::string
的其他 API 交互,或者只是想在您自己的代码中使用更好的表示形式。无论哪种情况,std::string
本身都可能是理想的解决方案。
std::string
类型已经支持两种类型之间的转换;例如:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <string>
void print_c_string(const char *arr)
{
printf("arr := '%s'\r\n", arr);
}
void print_std_string(std::string str)
{
std::cout << "str := '" << str << '\'' << std::endl;
}
int main(int argc, char *argv[])
{
// Get a C-style string
char *arr = (char *)malloc(strlen("c-style string") + 1);
memcpy(arr, "c-style string", strlen("c-style string"));
arr[strlen("c-style string")] = '[=10=]';
// Get a std::string
std::string str("standard lib string");
print_c_string(arr);
print_std_string(str);
// Get a std::string from the C-style string
std::string fromArr(arr);
print_std_string(fromArr);
// Get C-style string from std::string
print_c_string(str.c_str());
free(arr);
return 0;
}
// output:
// arr := 'c-style string'
// str := 'standard lib string'
// str := 'c-style string'
// arr := 'standard lib string'
就生命周期而言,从 char *
构建 std::string
将复制数据,因此生命周期不会耦合。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <string>
int main(int argc, char *argv[])
{
// Get a C-style string
char *arr = (char *)malloc(strlen("c-style string") + 1);
memcpy(arr, "c-style string", strlen("c-style string"));
arr[strlen("c-style string")] = '[=11=]';
{
std::string str(arr);
std::cout << "std::string from arr := '" << str << '\'' << std::endl;
str.clear();
std::cout << "cleared std::string from arr := '" << str << '\'' << std::endl;
}
printf("arr := '%s'\r\n", arr);
free(arr);
return 0;
}
// output:
// std::string from arr := 'c-style string'
// cleared std::string from arr := ''
// arr := 'c-style string'
另一方面,从 std::string
获取 char *
实际上会给出一个指向字符串数据的指针,因此您需要考虑 [=13= 的消费者如何] 会治疗的
#include <iostream>
#include <string>
int main(int argc, char *argv[])
{
const char *arr;
{
std::string str("standard lib string");
arr = str.c_str();
printf("arr := '%s'\r\n", arr);
// Modifying the data at the char * will affect the string, don't do this.
//
// http://www.cplusplus.com/reference/string/string/c_str/
// > A program shall not alter any of the characters in this sequence.
((char *)arr)[1] = '7';
std::cout << "str := '" << str << '\'' << std::endl;
// The implication here is that if an API is expecting a char * that it will
// modify or own then you'll need to copy the data out and manage the lifetime
// of the copy accordingly.
// Mutating the string will similarly change the data at the char *.
for (auto & c: str) c = toupper(c);
printf("arr := '%s'\r\n", arr);
}
// Once the string is gone there's no guarantee about the data at the char *.
// You'll need to make sure the string outlives the char * or make a copy of the data.
printf("arr := '%s'\r\n", arr);
return 0;
}
// output:
// arr := 'standard lib string'
// str := 's7andard lib string'
// arr := 'S7ANDARD LIB STRING'
// arr := ''
我在 C++98 中使用一个使用 C 风格数组的库。
我想隐藏所有这些并通过声明代码简单地与之交互。 我正在寻找类似这个伪代码的东西。 智能指针是一个挑战。
我可以使用 boost 1.61 的 boost 智能指针 https://www.boost.org/doc/libs/1_61_0/libs/smart_ptr/smart_ptr.htm
class ElegantArray
{
private:
char* array; // <<<==== should be a unique or auto ptr?
int size;
std::string aString;
public:
ElegantArray(char* array_, int size_) { // <<<=============should require a smart pointer
array = array_;
size = size_; //<<<===constructor leaves aString nil which requires nil checks =(
}
ElegantArray(std::string aString_) {
aString = aString_; // <<<===constructor leaves array and size nil which requires nil checks =(
}
std::string string() {
int i; //put inside for loop?
std::string strng = "";
for (i = 0; i < size; i++) { strng = strng + array[i]; }
return strng;
}
//How & What do i return here unique or auto ptr?
char* cArrayPointer() {
int n = aString.length();
char charArray[n+1];
strcpy(charArray, aString.c_str());
return charArray; // <<<==================should return a smart pointer
}
}
调用站点类似于
ElegantArray elegantArray(smartPointerToCArray, arraySize);
std::string aString = elegantArray.string();
和
ElegantArray elegantArray("Falalalala");
SmartPointerToCArray smartPointerToCArray = elegantArray.cArrayPointer();
请指教
我猜你说的是 char
的 c 数组。在这种情况下,您正在寻找 std::string
:
#include <string>
#include <iostream>
int main() {
typedef std::string ElegantArray;
char x[] = "Foo";
const char* y = "Bar";
ElegantArray a(x);
ElegantArray b(y);
ElegantArray c("Baz");
std::cout << a << " " << b << " " << c;
}
如果您需要 c 字符串,请使用 std::string::c_str()
。
我假设您正在使用处理 char *
的 API;需要与处理 std::string
的其他 API 交互,或者只是想在您自己的代码中使用更好的表示形式。无论哪种情况,std::string
本身都可能是理想的解决方案。
std::string
类型已经支持两种类型之间的转换;例如:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <string>
void print_c_string(const char *arr)
{
printf("arr := '%s'\r\n", arr);
}
void print_std_string(std::string str)
{
std::cout << "str := '" << str << '\'' << std::endl;
}
int main(int argc, char *argv[])
{
// Get a C-style string
char *arr = (char *)malloc(strlen("c-style string") + 1);
memcpy(arr, "c-style string", strlen("c-style string"));
arr[strlen("c-style string")] = '[=10=]';
// Get a std::string
std::string str("standard lib string");
print_c_string(arr);
print_std_string(str);
// Get a std::string from the C-style string
std::string fromArr(arr);
print_std_string(fromArr);
// Get C-style string from std::string
print_c_string(str.c_str());
free(arr);
return 0;
}
// output:
// arr := 'c-style string'
// str := 'standard lib string'
// str := 'c-style string'
// arr := 'standard lib string'
就生命周期而言,从 char *
构建 std::string
将复制数据,因此生命周期不会耦合。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <string>
int main(int argc, char *argv[])
{
// Get a C-style string
char *arr = (char *)malloc(strlen("c-style string") + 1);
memcpy(arr, "c-style string", strlen("c-style string"));
arr[strlen("c-style string")] = '[=11=]';
{
std::string str(arr);
std::cout << "std::string from arr := '" << str << '\'' << std::endl;
str.clear();
std::cout << "cleared std::string from arr := '" << str << '\'' << std::endl;
}
printf("arr := '%s'\r\n", arr);
free(arr);
return 0;
}
// output:
// std::string from arr := 'c-style string'
// cleared std::string from arr := ''
// arr := 'c-style string'
另一方面,从 std::string
获取 char *
实际上会给出一个指向字符串数据的指针,因此您需要考虑 [=13= 的消费者如何] 会治疗的
#include <iostream>
#include <string>
int main(int argc, char *argv[])
{
const char *arr;
{
std::string str("standard lib string");
arr = str.c_str();
printf("arr := '%s'\r\n", arr);
// Modifying the data at the char * will affect the string, don't do this.
//
// http://www.cplusplus.com/reference/string/string/c_str/
// > A program shall not alter any of the characters in this sequence.
((char *)arr)[1] = '7';
std::cout << "str := '" << str << '\'' << std::endl;
// The implication here is that if an API is expecting a char * that it will
// modify or own then you'll need to copy the data out and manage the lifetime
// of the copy accordingly.
// Mutating the string will similarly change the data at the char *.
for (auto & c: str) c = toupper(c);
printf("arr := '%s'\r\n", arr);
}
// Once the string is gone there's no guarantee about the data at the char *.
// You'll need to make sure the string outlives the char * or make a copy of the data.
printf("arr := '%s'\r\n", arr);
return 0;
}
// output:
// arr := 'standard lib string'
// str := 's7andard lib string'
// arr := 'S7ANDARD LIB STRING'
// arr := ''