如何赋予变量对pop()函数的访问权限



我有SStack.hSStack.cpp文件。

SStack.h文件中,有一个int used成员变量。我想在非成员函数中使用非静态pop()方法。使pop()在这些非成员函数中可用的唯一方法是将其声明为const。但当我这样做时,我不能使用this->used--;来递减used成员;弹出";顶部元素。

有没有办法在const方法中访问used变量?

SStack.h:

//CONTENTS: Declares Class SStack, with data members, contructors and member function prototypes
//If you want, you can make minor changes to this header file
#ifndef _StackClass_
#define  _StackClass_

#include <cstdlib>
#include <string>
#include <iostream>

using namespace std;
class SStack
{

public:
// Constructor
SStack( int cap);
// Copy Constructor
SStack( const SStack& s );
~SStack( ); //destructor

// The member function push: Precondition:  the stack is not full.
string push ( const std::string s);

// The member function pop: Precondition:  the stack is not empty.
string pop ();
// The member function top: Precondition:  the stack is not empty.
string top () const;

bool IsEmpty () const;
//printing all the elements in the stack
void print() const;
int size() const;
int getCapacity() const;

private:
int capacity; // Capacity is the maximum number of items that a stack can hold
std::string* DynamicStack; 
int used; // How many items are stored in the stack
};

// NONMEMBER FUNCTIONS for the stack class
// Postcondition: The stack returned is the union of s1 and s2.
SStack operator +(const SStack& s1, const SStack& s2);

//Return true if the two stacks contain exactly the same element values in the same order. 
bool equals(const SStack& s1, const SStack& s2);

#endif

SStack.cpp


#include <iostream>
#include "SStack.h"
SStack::SStack(int cap)
{
DynamicStack = new string[cap];
this->capacity = cap;
this->used = -1;
}
SStack::SStack(const SStack& s)
{
capacity = s.capacity;
DynamicStack = new string[capacity];
used = s.used;
for (int i = 0; i < used; i++) {
DynamicStack[i] = s.DynamicStack[i];
}
}
SStack::~SStack()
{
}
string SStack::push(const std::string s)
{
if (used >= capacity - 1) {
cout << "Stack overflow" << endl;
}
else {
this->used++;
DynamicStack[used] = s;
std::cout << s << " pushed onto the stack" << endl;
return s;
}
}
string SStack::pop() 
{
if (used < 0) {
cout << "stack underflow" << endl;
}
else {
string s = DynamicStack[used];
this->used--;
cout << "popped off the top element: " << s << endl;
return s;
}
}
string SStack::top() const
{
if (used < 0) {
cout << "stack is empty" << endl;
return " ";
}
else {
string s = DynamicStack[used];
std::cout << s << " is on top" << endl;
return s;
}
}
bool SStack::IsEmpty() const
{
if (used < 0) {
return true;
}
else {
return false;
}
}
void SStack::print() const
{
int counter = 1;
for (int i = used; i >= 0; i--) {
std::cout << counter << ":";
std::cout << DynamicStack[i] << endl;
counter++;
}
}
int SStack::size() const
{
std::cout << "the size of the stack is:" << used + 1 << endl;
return used;
}
int SStack::getCapacity() const
{
std::cout << "The capacity of the stack is: " << capacity << endl;
return capacity;
}
SStack operator+(const SStack& s1, const SStack& s2)
{
return 0;
}
bool equals(const SStack& s1, const SStack& s2)
{

if (s1.size() == s2.size()) {
for (int i = 0; i < s1.size(); i++) {
if (s1.top() != s2.top()) {
std::cout << "the stacks are not equal" << endl;
return false;
}
s1.pop(); //does not work because pop doesnt have the const type
s2.pop();// same as above
}
std::cout << "the stacks are equal" << endl;
return true;
}
else {
std::cout << "the stacks are not equal" << endl;
return false;
}
}

在此函数中:

bool equals(const SStack& s1, const SStack& s2)
{
// ...  
s1.pop();  // error
s2.pop();  // error
}

您会得到一个错误,因为pop是一个非常数函数,但s1s2是const对象,这意味着只能对它们调用const成员函数。

由于pop本质上是一个非常数运算,因此尝试将其作为const成员是没有意义的。


相反,您可以在不使用pop的情况下实现equals。这可以通过使equals成为SStackfriend来实现,从而它可以在根本不必调用pop的情况下检查底层存储。

类似的方法是编写一个成员函数(operator==是一个合理的选择(来比较2个SStacks,然后您可以从equals调用该函数。


或者您可以通过复制接受equal的参数:

bool equals(SStack s1, SStack s2) {
// ...
s1.pop();  // ok
s2.pop();  // ok
}

这在技术上解决了这个问题,而且是正确的,但可能效率非常低,因为您正在围绕潜在的大型对象进行复制。

const方法不能更改对象的成员。equal()应该const引用作为输入,但它不应该更改正在比较的堆栈。

您可以将equal()设置为SStackfriend,这样它就可以直接对其内部阵列执行非破坏性迭代(与operator+相同(,例如:

class SStack
{
...
public:
...
friend bool equals (const SStack& s1, const SStack& s2);
friend SStack operator +(const SStack& s1, const SStack& s2);
};
bool equals(const SStack& s1, const SStack& s2);
SStack operator +(const SStack& s1, const SStack& s2);
SStack operator+(const SStack& s1, const SStack& s2)
{
SStack res(s1.size() + s2.size());
for (int i = 0; i < s1.size(); i++) {
res.push(s1.DynamicStack[i]);
}
for (int i = 0; i < s2.size(); i++) {
res.push(s2.DynamicStack[i]);
}
return res;
}
bool equal(const SStack& s1, const SStack& s2)
{
if (s1.size() != s2.size()) {
std::cout << "the stacks are not equal" << endl;
return false;
}
for (int i = 0; i < s1.size(); i++) {
if (s1.DynamicStack[i] != s2.DynamicStack[i]) {
std::cout << "the stacks are not equal" << endl;
return false;
}
}
std::cout << "the stacks are equal" << endl;
return true;
}

或者,您可以实现一个公共const成员operator==,然后equal()可以调用该成员(以及operator+可以调用的成员operator+=(,而不使它们成为friend,例如:

class SStack
{
...
public:
...
bool operator ==(const SStack& rhs) const;
SStack& operator +=(const SStack& rhs);
};
bool equals(const SStack& s1, const SStack& s2);
SStack operator +(const SStack& s1, const SStack& s2);
bool SStack::operator==(const SStack& rhs) const
{
if (size() != rhs.size()) {
std::cout << "the stacks are not equal" << endl;
return false;
}
for (int i = 0; i < used; i++) {
if (DynamicStack[i] != s.DynamicStack[i]) {
std::cout << "the stacks are not equal" << endl;
return false;
}
}
std::cout << "the stacks are equal" << endl;
return true;
}
SStack& Stack::operator+=(const SStack& rhs)
{
for (int i = 0; i < rhs.size(); i++) {
push(rhs.DynamicStack[i]);
}
return *this;
}
bool equals(const SStack& s1, const SStack& s2)
{
return (s1 == s2);
}
SStack operator+(const SStack& s1, const SStack& s2)
{
SStack res(s1.size() + s2.size);
res += s1;
res += s2;
return res;
}

最新更新