Copy Control and Resource Management(valuelike or pointerlike)

本文探讨了拷贝控制和资源管理的重要性,并通过两个示例:值类和指针类,展示了如何正确实现拷贝构造函数、赋值操作符及析构函数。文章还介绍了引用计数的方法来管理共享资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Copy Control and Resource Management

     we first have to decide what copying an object of our type will mean. In general, we have two choices: We can define the copy operations to make the class behave like a value or like a pointer.

1、Classes That Act Like Values

(1)、A copy constructor that copies the string, not just the pointer
(2)、A destructor to free the string
(3)、A copy-assignment operator to free the object’s existing string and copy the string from its right-hand operand

The valuelike version of HasPtr is as follow:

class HasPtr {
public:
        HasPtr(const std::string &s = std::string()): ps(new std::string(s)), i(0) { }
        // each HasPtr has its own copy of the string to which ps points
        HasPtr(const HasPtr &p): ps(new std::string(*p.ps)), i(p.i) { }
        HasPtr& operator=(const HasPtr &rhs)
        {
            auto newp = new string(*rhs.ps); // copy the underlying string
            delete ps; // free the old memory
            ps = newp; // copy data from rhs into this object
            i = rhs.i;
            return *this; // return this object
        }
        ~HasPtr() { delete ps; }
private:
        std::string *ps;
        int i;
};

Key Concept: Assignment Operators
There are two points to keep in mind when you write an assignment operator:
(1)、Assignment operators must work correctly if an object is assigned to itself.

(2)、Most assignment operators share work with the destructor and copy constructor


2、Classes That Act Like Pointers

Reference counting works as follows:

(1): In addition to initializing the object, each constructor (other than the copy constructor) creates a counter.This counter will keep track of how many objects share state with the object we are creating. When we create an object, there is only one such object, so we initialize the counter to 1.
(2): The copy constructor does not allocate a new counter; instead, it copies the data members of its given object, including the counter. The copy constructor increments this shared counter, indicating that there is another user of that object’s state.
(3): The destructor decrements the counter, indicating that there is one less user of the shared state. If the count goes to zero, the destructor deletes that state.
(4): The copy-assignment operator increments the right-hand operand’s counter and decrements the counter of the left-hand operand. If the counter for the left-hand operand goes to zero, there are no more users. In this case, the copy-assignment operator must destroy the state of the left-hand operand

#include <string>

class HasPtr {
public:
    HasPtr(const std::string& s = std::string())
        : ps(new std::string(s)), i(0), use(new size_t(1))
    {
    }
    HasPtr(const HasPtr& hp) : ps(hp.ps), i(hp.i), use(hp.use) { ++*use; }
    HasPtr& operator=(const HasPtr& rhs)
    {
        ++*rhs.use;
        if (--*use == 0) {
            delete ps;
            delete use;
        }
        ps = rhs.ps;
        i = rhs.i;
        use = rhs.use;
        return *this;
    }
    ~HasPtr()
    {
        if (--*use == 0) {
            delete ps;
            delete use;
        }
    }

private:
    std::string* ps;
    int i;
    size_t* use;
};









### Minimal Bash-Like Line Editing Implementation Minimal bash-like line editing refers to the ability of command-line interfaces (CLI) to provide basic features such as cursor movement, history navigation, and simple text manipulation similar to those found in more advanced shells like `bash`. For single-user systems where resources might be limited, implementing these functionalities can significantly enhance usability without requiring extensive overhead. A straightforward approach involves using libraries that support terminal handling capabilities. One common choice is the GNU Readline library which provides powerful facilities for reading lines from an input stream while offering many useful functions including: - Command history management. - Programmable key bindings. - Completion mechanisms. - Textual search through previous commands[^1]. However, given constraints on resource usage typical in minimal environments, lighter alternatives exist. The linenoise library offers a lightweight yet effective option specifically designed for embedding into applications needing only essential line-editing functionality. Linenoise supports: - Basic arrow keys for moving around within the current line. - Simple cut/copy/paste operations via keyboard shortcuts. - Accessible API suitable for integration with various programming languages. For developers preferring even lower-level control over how each aspect works, crafting custom solutions based on direct interaction with terminals becomes viable. This method typically includes utilizing ANSI escape codes or other platform-specific APIs to manipulate console behavior directly. Here's a brief example demonstrating this concept in C++: ```cpp #include <iostream> #include <string> void moveCursorLeft() { std::cout << "\033[D"; // Move cursor one position left } int main() { std::string userInput; std::getline(std::cin, userInput); if (!userInput.empty()) { moveCursorLeft(); std::cout << "*"; } } ``` This snippet shows sending an ANSI sequence (`\033[D`) to shift the cursor back by one character when processing user inputs. Such techniques allow building up increasingly sophisticated behaviors tailored exactly according to project requirements.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值