在这篇文章,我们创造一个自定义的C++字符串类,它具备基本的string操作功能。

为什么要创建自己的字符串类呢?其中的一个原因是,当你想要让自己的字符串类型区别于一般的string时,你就需要自定义字符串类。例如,在证券期货的交易策略服务系统中,策略一般具有“策略ID”和“策略实例ID”的属性,他们都是字符串类型。如果你想要在C++代码中严格的限定某些函数调用参数,如果应该输入“策略实例ID”,程序员不会由于粗心而错误的传入“策略ID”。你就需要实现自己的策略实例ID和策略ID。

废话不多说,我先上参考代码。下面的代码段就是策略ID和策略实例ID的代码。两者几乎一模一样,但是在C++编译过程中可以严格的区分两种类型,这就可以让编译器解决很多编码问题。


namespace framework
{class StrategyId
{
public:StrategyId() {}StrategyId(const std::string& value) : value_(value) {}StrategyId(const char* value) : value_(value) {}operator std::string() const { return value_; }std::string str_value() const { return value_; }void str_value(const std::string& value) { value_ = value; }bool empty() const { return value_.empty(); }const char* c_str() const { return value_.c_str(); }bool operator==(const std::string& other) const { return other == value_; }bool operator==(const char* other) const { return other == value_; }size_t length() const { return value_.length(); }private:std::string value_;
};class StrategyInstId
{
public:StrategyInstId() {}StrategyInstId(const std::string& value) : value_(value) {}StrategyInstId(const char* value) : value_(value) {}operator std::string() const { return value_; }std::string str_value() const { return value_; }void str_value(const std::string& value) { value_ = value; }bool empty() const { return value_.empty(); }const char* c_str() const { return value_.c_str(); }bool operator==(const std::string& other) const { return other == value_; }bool operator==(const char* other) const { return other == value_; }size_t length() const { return value_.length(); }private:std::string value_;
};

在本实例代码中,因为使用了fmtlib/fmt类库和daniele77/cli,还需要做相应的函数重载。另外,为了支持两种ID作为std::unordered_map的哈希键值(hash key),也需要自定义Key类型重载。我把这些代码放在了额外的"instance-inl.h"中。

#pragma oncenamespace fmt
{
namespace v6
{template <>
struct formatter<framework::StrategyId> : fmt::formatter<std::string>
{auto format(const framework::StrategyId& s, fmt::format_context& ctx){return fmt::formatter<std::string>::format(s.str_value(), ctx);}
};template <>
struct formatter<framework::StrategyInstId> : fmt::formatter<std::string>
{auto format(const framework::StrategyInstId& s, fmt::format_context& ctx){return fmt::formatter<std::string>::format(s.str_value(), ctx);}
};} // namespace v6
} // namespace fmtnamespace std
{
extern GWSDK_API ostream& operator<<(ostream& os, const framework::StrategyId& v);
extern GWSDK_API ostream& operator<<(ostream& os, const framework::StrategyInstId& v);
extern GWSDK_API istream& operator>>(istream& is, framework::StrategyId& v);
extern GWSDK_API istream& operator>>(istream& is, framework::StrategyInstId& v);template <> struct hash<framework::StrategyId>
{std::size_t operator()(const framework::StrategyId& k) const{using std::hash;using std::size_t;using std::string;// Compute individual hash values for first,// second and third and combine them using XOR// and bit shifting:return hash<string>()(k.str_value());}
};
template <> struct hash<framework::StrategyInstId>
{std::size_t operator()(const framework::StrategyInstId& k) const{using std::hash;using std::size_t;using std::string;// Compute individual hash values for first,// second and third and combine them using XOR// and bit shifting:return hash<string>()(k.str_value());}
};} // namespace std#include "cli/cli.h"namespace cli
{
template <> struct TypeDesc<framework::StrategyId>
{static const char* Name() { return "<framework::StrategyId>"; }
};
template <> struct TypeDesc<framework::StrategyInstId>
{static const char* Name() { return "<framework::StrategyInstId>"; }
};}

我在实现OpenOrderCTP的时候使用了这些代码技术。OpenOrderCTP是上海期货交易所CTP API接口的二次封装,在普通机器上内部时延<30微妙,它实现委托状态和成交的严格排序与缓存、重演,实现了事务级别的原子交易功能,实现了复杂订单、多个委托打包自动重发的功能,还可以省心支持对接CTP之外的其他证券交易柜台,如LTS、QMT、UFT、TradeX等。如需技术支持和咨询,请联系微信号: funrun2019(下方扫码)。

下面的文章摘录自国外友人的网页,可做参考。

The string class has the following basic functionalities:

  1. Constructor with no arguments: This allocates the storage for the string object in the heap and assign the value as a NULL character.
  2. Constructor with only one argument : It accepts a pointer to a character or we can say if we pass an array of characters, accepts the pointer to the first character in the array then the constructor of the String class allocates the storage on the heap memory of the same size as of the passed array and copies the contents of the array to that allocated memory in heap. It copies the contents using the strcpy() function declared in cstring library.
    Before doing the above operation it checks that if the argument passed is a NULL pointer then it behaves as a constructor with no arguments.
  3. Copy Constructor: It is called when any object created of the same type from an already created object then it performs a deep copy. It allocates new space on the heap for the object that is to be created and copies the contents of the passed object(that is passed as a reference).
  4. Move Constructor: It is typically called when an object is initialized(by direct-initialization or copy-initialization) from rvalue of the same type. It accepts a reference to an rvalue of an object of the type of custom string class.

Below is the implementation of the above methods using custom string class Mystring:

filter_none

edit

play_arrow

brightness_4

// C++ program to illustrate the

// above discussed functionality

#include <cstring>

#include <iostream>

using namespace std;

 

// Custom string class

class Mystring {

 

    // Initialise the char array

    char* str;

 

public:

    // No arguments Constructor

    Mystring();

 

    // Constructor with 1 arguments

    Mystring(char* val);

 

    // Copy Constructor

    Mystring(const Mystring& source);

 

    // Move Constructor

    Mystring(Mystring&& source);

 

    // Destructor

    ~Mystring() { delete str; }

};

 

// Function to illustrate Constructor

// with no arguments

Mystring::Mystring()

    : str{ nullptr }

{

    str = new char[1];

    str[0] = '\0';

}

 

// Function to illustrate Constructor

// with one arguments

Mystring::Mystring(char* val)

{

    if (val == nullptr) {

        str = new char[1];

        str[0] = '\0';

    }

 

    else {

 

        str = new char[strlen(val) + 1];

 

        // Copy character of val[]

        // using strcpy

        strcpy(str, val);

 

        cout << "The string passed is: "

             << str << endl;

    }

}

 

// Function to illustrate

// Copy Constructor

Mystring::Mystring(const Mystring& source)

{

    str = new char[strlen(source.str) + 1];

    strcpy(str, source.str);

}

 

// Function to illustrate

// Move Constructor

Mystring::Mystring(Mystring&& source)

{

    str = source.str;

    source.str = nullptr;

}

 

// Driver Code

int main()

{

    // Constructor with no arguments

    Mystring a;

 

    // Convert string literal to

    // char array

    char temp[] = "Hello";

 

    // Constructor with one argument

    Mystring b{ temp };

 

    // Copy constructor

    Mystring c{ a };

 

    char temp1[] = "World";

 

    // One arg constructor called,

    // then the move constructor

    Mystring d{ Mystring{ temp } };

    return 0;

}

Output:

The string passed is: Hello
The string passed is: Hello

Some more functionalities of string class:

  1. pop_back(): Removes the last element from the Mystring object.
  2. push_back(char ch): Accepts a character as an argument and adds it to the end of the Mystring object.
  3. length(): Returns the length of the mystring.
  4. copy(): It copies the mystring object to a character array from a given position(pos) and a specific length(len).
  5. swap(): It swaps the two Mystring objects.
  6. Concatenate two strings using overloading the ‘+’ operator: Allows us to concatenate two strings.

Below is the program to illustrate the above-discussed functionality:

filter_none

edit

play_arrow

brightness_4

// C++ program to illustrate the

// above functionalities

#include <cstring>

#include <iostream>

using namespace std;

 

// Class Mystring

class Mystring {

 

    // Prototype for stream insertion

    friend ostream&

    operator<<(

        ostream& os,

        const Mystring& obj);

 

    // Prototype for stream extraction

    friend istream& operator>>(

        istream& is,

        Mystring& obj);

 

    // Prototype for '+'

    // operator overloading

    friend Mystring operator+(

        const Mystring& lhs,

        const Mystring& rhs);

    char* str;

 

public:

    // No arguments constructor

    Mystring();

 

    // pop_back() function

    void pop_bk();

 

    // push_back() function

    void push_bk(char a);

 

    // To get the length

    int get_length();

 

    // Function to copy the string

    // of length len from position pos

    void cpy(char s[], int len, int pos);

 

    // Swap strings function

    void swp(Mystring& rhs);

 

    // Constructor with 1 arguments

    Mystring(char* val);

 

    // Copy Constructor

    Mystring(const Mystring& source);

 

    // Move Constructor

    Mystring(Mystring&& source);

 

    // Overloading the assignment

    // operator

    Mystring& operator=(

        const Mystring& rhs);

 

    // Destructor

    ~Mystring() { delete str; }

};

 

// Overloading the assignment operator

Mystring& Mystring::operator=(

    const Mystring& rhs)

{

    if (this == &rhs)

        return *this;

    delete[] str;

    str = new char[strlen(rhs.str) + 1];

    strcpy(str, rhs.str);

    return *this;

}

 

// Overloading the plus operator

Mystring operator+(const Mystring& lhs,

                   const Mystring& rhs)

{

    int length = strlen(lhs.str)

                 + strlen(rhs.str);

 

    char* buff = new char[length + 1];

 

    // Copy the strings to buff[]

    strcpy(buff, lhs.str);

    strcat(buff, rhs.str);

 

    // String temp

    Mystring temp{ buff };

 

    // delete the buff[]

    delete[] buff;

 

    // Return the concatenated string

    return temp;

}

// Overloading the stream

// extraction operator

istream& operator>>(istream& is,

                    Mystring& obj)

{

    char* buff = new char[1000];

    is >> buff;

    obj = Mystring{ buff };

    delete[] buff;

    return is;

}

 

// Overloading the stream

// insertion operator

ostream& operator<<(ostream& os,

                    const Mystring& obj)

{

    os << obj.str;

    return os;

}

 

// Function for swapping string

void Mystring::swp(Mystring& rhs)

{

    Mystring temp{ rhs };

    rhs = *this;

    *this = temp;

}

 

// Function to copy the string

void Mystring::cpy(char s[], int len,

                   int pos)

{

    for (int i = 0; i < len; i++) {

        s[i] = str[pos + i];

    }

    s[len] = '\0';

}

 

// Function to implement push_bk

void Mystring::push_bk(char a)

{

    // Find length of string

    int length = strlen(str);

 

    char* buff = new char[length + 2];

 

    // Copy character from str

    // to buff[]

    for (int i = 0; i < length; i++) {

        buff[i] = str[i];

    }

    buff[length] = a;

    buff[length + 1] = '\0';

 

    // Assign the new string with

    // char a to string str

    *this = Mystring{ buff };

 

    // Delete the temp buff[]

    delete[] buff;

}

 

// Function to implement pop_bk

void Mystring::pop_bk()

{

    int length = strlen(str);

    char* buff = new char[length];

 

    // Copy character from str

    // to buff[]

    for (int i = 0; i < length - 1; i++)

        buff[i] = str[i];

    buff[length] = '\0';

 

    // Assign the new string with

    // char a to string str

    *this = Mystring{ buff };

 

    // delete the buff[]

    delete[] buff;

}

 

// Function to implement get_length

int Mystring::get_length()

{

    return strlen(str);

}

 

// Function to illustrate Constructor

// with no arguments

Mystring::Mystring()

    : str{ nullptr }

{

    str = new char[1];

    str[0] = '\0';

}

 

// Function to illustrate Constructor

// with one arguments

Mystring::Mystring(char* val)

{

    if (val == nullptr) {

        str = new char[1];

        str[0] = '\0';

    }

 

    else {

 

        str = new char[strlen(val) + 1];

 

        // Copy character of val[]

        // using strcpy

        strcpy(str, val);

    }

}

 

// Function to illustrate

// Copy Constructor

Mystring::Mystring(const Mystring& source)

{

    str = new char[strlen(source.str) + 1];

    strcpy(str, source.str);

}

 

// Function to illustrate

// Move Constructor

Mystring::Mystring(Mystring&& source)

{

    str = source.str;

    source.str = nullptr;

}

 

// Driver Code

int main()

{

    // Constructor with no arguments

    Mystring a;

 

    // Convert string literal to

    // char array

    char temp[] = "Hello";

 

    // Constructor with one argument

    Mystring b{ temp };

 

    // Copy constructor

    Mystring c{ a };

 

    char temp1[] = "World";

 

    // One arg constructor called,

    // then the move constructor

    Mystring d{ Mystring{ temp } };

 

    // Remove last character from

    // Mystring b

    b.pop_bk();

 

    // Print string b

    cout << "Mystring b: "

         << b << endl;

 

    // Append last character from

    // Mystring b

    b.push_bk('o');

 

    // Print string b

    cout << "Mystring b: "

         << b << endl;

 

    // Print length of string b

    cout << "Length of Mystring b: "

         << b << endl;

 

    char arr[80];

 

    // Copy string b chars from

    // length 0 to 3

    b.cpy(arr, 3, 0);

 

    // Print string arr

    cout << "arr is: "

         << arr << endl;

 

    // Swap d and b

    d.swp(b);

 

    // Print d and b

    cout << d << " "

         << b << endl;

 

    // Concatenate b and b with

    // overloading '+' operator

    d = b + b;

 

    // Print string d

    cout << "string d: "

         << d << endl;

 

    return 0;

}

Output:

Mystring b: Hell
Mystring b: Hello
Length of Mystring b: Hello
arr is: Hel
Hello Hello
string d: HelloHello

Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: DSA Self Paced. Become industry ready at a student-friendly price.

如何实现一个具备基本功能函数的C++的自定义String字符串类相关推荐

  1. 国密SM9算法C++实现之四:基本功能函数与KGC接口的实现

    SM9算法C++实现系列目录: 基于JPBC的SM9算法的java实现与测试 国密SM9算法C++实现之0:源码下载地址 国密SM9算法C++实现之一:算法简介 国密SM9算法C++实现之二:测试工具 ...

  2. 写一个函数,2 个参数,1 个字符串,1 个字节数,返回截取的字符串,要求字符串中的中文不能出现乱码

    题目要求: 写一个函数,2 个参数,1 个字符串,1 个字节数,返回截取的字符串,要求字符串中的中文不能出现乱码. 如("我ABC",4)应该截为"我AB", ...

  3. python创建一个字典、关键字为只包含字母的字符串_探究Python源码,终于弄懂了字符串驻留技术...

    摘要:在本文中,我们将深入研究 Python 的内部实现,并了解 Python 如何使用一种名为字符串驻留(String Interning)的技术,实现解释器的高性能. 每种编程语言为了表现出色,并 ...

  4. 用户自定义一个异常,编程创建并抛出某个异常类的实例。运行该程序并观察执行结果。

    用户自定义一个异常,编程创建并抛出某个异常类的实例.运行该程序并观察执行结果. 例:用户密码的合法化验证. 要求密码有4-6个数字组成.若长度不落在这个范围或不是有数字组成.抛出自己的异常. 要求: ...

  5. php定义一个名为Vehicles,php的扩展和嵌入--c++类的扩展开发

    配置文件:config.m4 1 PHP_ARG_ENABLE(vehicles, 2 [Whether to enable the "vehicles" extension], ...

  6. Java黑皮书课后题第6章:*6.20(计算一个字符串中字母的个数)编写一个方法,使用下面的方法体计算字符串中的字母个数。编写一个测试程序,提示用户输入字符串,然后显示字符串中的字母个数

    6.20(计算一个字符串中字母的个数)编写一个方法,使用下面的方法体计算字符串中的字母个数.编写一个测试程序,提示用户输入字符串,然后显示字符串中的字母个数 题目 题目描述 破题 代码 运行示例 题目 ...

  7. Arrays.asList()返回的ArrayList,这是Arrays里内嵌的一个私有静态类,而并不是java.util.ArrayList类

    测试代码: package array;import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; ...

  8. C语言试题三十二之编写函数function,它的功能是:将一个字符串转换为一个整数(不得调用c语言提供的将字符串转换为整数的函数)。

    1. 题目 请编写函数function,它的功能是:将一个字符串转换为一个整数(不得调用c语言提供的将字符串转换为整数的函数). 2 .温馨提示 C试题汇总里可用于计算机二级C语言笔试.机试.研究生复 ...

  9. php mysql 随机字符串_MySQL_Mysql 自定义随机字符串的实现方法,前几天在开发一个系统,需要 - phpStudy...

    Mysql 自定义随机字符串的实现方法 前几天在开发一个系统,需要用到随机字符串,但是mysql的库函数有没有直接提供,就简单的利用现有的函数东拼西凑出随机字符串来.下面简单的说下实现当时. 1.简单 ...

最新文章

  1. vivado调用modelsim
  2. 深拷贝与浅拷贝~动态内存释放有关
  3. SAP常见问题与解决办法 2
  4. Python中if条件判断语句的用法!
  5. Matlab生成棋盘格点图
  6. 别把数据当成万金油,如何用OKR搞垮一个团队?
  7. 主题模型TopicModel:LDA编程实现
  8. GRS认证咨询,GRS认证审核文件清单进行整改,可以参考哪些内容?
  9. 235款鼠标样式免费下载
  10. Unity3D Gamma,Linear和sRGB
  11. day06 Elasticsearch搜索引擎2
  12. Basler驱动如何彩色相机白平衡说明
  13. 线性代数二次型标准化的方法总结
  14. 【计组】字长、数据总线、地址总线
  15. 在excel图表上添加数据标签
  16. Python作业“骰子游戏”
  17. Eclipse : java连接数据库MySQL超详细步骤
  18. 销客多后台分佣发放,提现申请 批量微信付款操异常
  19. 饿汉式 and 懒汉式
  20. pajek study

热门文章

  1. 用户权限匹配中英文翻译
  2. MWC21上海全球首秀,全馆通行证先到先得
  3. VMware彻底删除虚拟机操作系统的方法
  4. 2021年中国研究生数学建模竞赛C题帕金森病的脑深部电刺激治疗建模研究题目及思路参考代码
  5. python 去除不可见字符\u200b 方法收集
  6. ios安卓模拟器_【MOD3.0】崩坏3 跨端/改服 安装包 V3.0.0 [iOS/安卓]
  7. 弹出模式窗口的returnValue问题
  8. 今天,正式介绍一下Java极客技术知识星球
  9. 姜奇平:互联网带来了商业文化的变革
  10. 基于springboot的超市管理系统(源码+数据库)003