You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于多态实现根据用户输入调用对应进制转换函数

Solution Using Polymorphism for Base Conversion

Let's fix your code step by step to implement a clean polymorphic solution for converting numbers from different bases to decimal. Here's what we need to address:

Key Issues in Your Original Code

  • You can't instantiate an abstract base class (like Base) directly because it contains pure virtual functions (marked with =0).
  • The toDec function wasn't properly designed for polymorphism—it should be a pure virtual function that each derived class implements.
  • Derived classes (Hex, Binary) didn't have constructors to initialize the base class correctly.
  • You needed a way to dynamically create the right derived class instance based on user input (a factory pattern).

Revised Implementation

Step 1: Refactor the Abstract Base Class

First, we'll define a clean interface with a pure virtual toDec function and a virtual destructor (critical for proper memory cleanup when using polymorphism):

#include <iostream>
#include <string>
#include <cstdlib> // For strtoull
#include <memory>  // For smart pointers (optional but recommended)

using namespace std;

class Base {
public:
    Base(string n, string b) : number(n), base(b) {}
    virtual ~Base() = default; // Virtual destructor to ensure proper cleanup
    virtual double toDec() const = 0; // Pure virtual: must be implemented by derived classes
protected:
    string number; // The number string in the original base
    string base;   // The base type (e.g., "hex", "binary")
};

Step 2: Implement Derived Classes

Each derived class will handle its own conversion to decimal. We'll use strtoull (string to unsigned long long) with the appropriate base parameter:

class Hex : public Base {
public:
    Hex(string n) : Base(n, "hex") {} // Initialize base class with number and "hex"
    
    double toDec() const override {
        char* endPtr;
        // Convert hex string to unsigned long long, then cast to double
        unsigned long long decimalVal = strtoull(number.c_str(), &endPtr, 16);
        return static_cast<double>(decimalVal);
    }
};

class Binary : public Base {
public:
    Binary(string n) : Base(n, "binary") {} // Initialize base class with number and "binary"
    
    double toDec() const override {
        char* endPtr;
        // Convert binary string to unsigned long long, then cast to double
        unsigned long long decimalVal = strtoull(number.c_str(), &endPtr, 2);
        return static_cast<double>(decimalVal);
    }
};

Step 3: Factory Function for Dynamic Object Creation

This function takes the user's input (number and base type) and returns a pointer to the correct derived class instance. This is how we achieve dynamic polymorphism without cluttering the main logic with if/switch (the logic is isolated to the factory):

// Using unique_ptr to avoid memory leaks (recommended)
unique_ptr<Base> createNumber(const string& number, const string& baseType) {
    if (baseType == "hex") {
        return make_unique<Hex>(number);
    } else if (baseType == "binary") {
        return make_unique<Binary>(number);
    }
    // Add more base cases here (e.g., "decimal", "octal")
    return nullptr; // Return null if base type is unknown
}

Step 4: Main Function

Now we can use the factory function to dynamically create the right object and call toDec() polymorphically:

int main() {
    string number, baseType;
    cout << "Enter number and base (e.g., 1A hex or 1010 binary): ";
    cin >> number >> baseType;
    
    unique_ptr<Base> num = createNumber(number, baseType);
    if (num) {
        cout << "Decimal value: " << num->toDec() << endl;
    } else {
        cout << "Error: Unknown base type!" << endl;
    }
    
    return 0;
}

Why This Works

  • Polymorphism: When we call num->toDec(), the correct implementation (from Hex or Binary) is invoked at runtime based on the actual object type.
  • Abstract Base Class: Enforces that all derived classes implement toDec(), ensuring a consistent interface.
  • Factory Pattern: Isolates the logic of creating objects, making it easy to add new bases (like Octal) later without changing the main code.

Notes

  • Error Handling: The current code assumes valid input. You might want to add checks (e.g., ensure hex strings only contain valid characters 0-9, A-F).
  • Smart Pointers: Using unique_ptr automatically manages memory, so you don't have to manually delete objects (avoiding memory leaks).
  • Alternative Conversion: If you need to handle larger numbers or floating points, you could adjust the toDec return type or use different conversion functions.

内容的提问来源于stack exchange,提问作者mhm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:13:25