简体   繁体   English

C++自定义结构化数组下标运算符重载怎么办?

[英]How to do C++ custom structured array subscript operator overload?

I want to provide an subscript operator structure for the struct I am writing.我想为我正在编写的结构提供一个下标运算符结构。 I plan to do this with two struct s foo and bar .我打算用两个struct s foobar来做这件事。 Code is as follows:代码如下:

#include <iostream>
struct foo;

struct bar{
    uint32_t *mem;
    uint32_t *opcode;

    bar():mem(nullptr),opcode(nullptr){}
    bar( foo *f, int index ){
        this->mem = f->memory + (index%16);
        this->opcode = f->instructions +(index%16);
    }
    operator bool(){ return (this->mem != nullptr) & (this->opcode != nullptr); }
};
std::ostream& operator<<( std::ostream& os, bar &t ){
    if( t ){
        return os << "bar:" << (*t.mem) << "\t-\t" << (*t.opcode);
    }else{
        return os << "bar: NOT INITIALIZED";
    }
}

struct foo{

    uint32_t *memory = new uint32_t[16]();
    uint32_t *instructions = new uint32_t[16]();

    foo(){}

    ~foo(){
        delete[] this->memory;
        delete[] this->instructions;
    }

   bar &operator[]( int index){
      return bar( *this, index%16 );
   } 

};
std::ostream& operator<<( std::ostream& os, foo &f ){
    for( int i =0 ; i < 16; i++ ){
        os << f.memory[i] << "\t" << f.instructions[i] << "\n";
    }
    return os;
}

I am using CygWin[x86_64] and Notepad++ as main compiler and editor on Windows 7 64 bit.我在 Windows 7 64 位上使用 CygWin[x86_64] 和 Notepad++ 作为主编译器和编辑器。

I have tried a lot of permutations on my own to fix this problem, but I would like to show the following:我自己尝试了很多排列来解决这个问题,但我想展示以下内容:

bar( foo *f, int index ){
    this->mem = f->memory + (index%16);
    this->opcode = f->instructions +(index%16);
}

and 

bar( foo *f, int index ){
    this->mem = f->memory[index%16];
    this->opcode = f->memory[index%16];
}

'f' is incomplete type error, with note that I have used forward declaration. 'f' 是不完整的类型错误,请注意我使用了前向声明。

bar( foo *f, int index ){
    this->mem = f->memory[index%16];
    this->opcode = f->memory[index%16];
}

two forward declarations notes, and two invalid use of incomplete type struct foo on this->mem = f->memory[index%16] and this->opcode = f->memory[index%16];两个前向声明注释,以及this->mem = f->memory[index%16]this->opcode = f->memory[index%16];上的两个不完整类型struct foo的无效使用;


I have tried a bunch of other stuff but it seems I have mostly an issue with incomplete type .我已经尝试了很多其他的东西,但似乎我主要遇到了incomplete type的问题。 I have searched SO for answers, and one did explain what is incomplete type , other issue was about recursive definition and this one doesn't define how to make an incomplete type complete .我已经搜索了答案,其中一个确实解释了什么是不完整类型,另一个问题是关于递归定义,而这个问题没有定义如何使不完整类型完整

I am hung on this for past several days, going trough iterations for simple operator overloading.在过去的几天里,我一直坚持这一点,为简单的运算符重载进行了迭代。 Maybe I am phrasing it wrong in questions, or searching for wrong answers.也许我在问题中措辞错误,或者在寻找错误的答案。

But can someone point out my mistakes and/or write how to overload array subscript operator with code and not just body less functions?但是有人可以指出我的错误和/或编写如何用代码重载数组下标运算符,而不仅仅是无体函数吗?

Basic design problems (which don't relate to your question) aside, there are two three things that keep this from compiling:除了基本的设计问题(与您的问题无关)之外,还有两三件事阻止了它的编译:

  1. The body of the constructor bar::bar(foo*,int) is defined inline, and uses members from foo .构造函数bar::bar(foo*,int)的主体是内联定义的,并使用来自foo的成员。 Since foo isn't defined yet (it's an incomplete type ), the compiler chokes because it doesn't know about the members of foo yet.由于foo还没有定义(它是一个不完整的类型),编译器因为还不知道foo的成员而窒息。

  2. When you call the constructor, you pass in a foo & , not a foo * .调用构造函数时,传入的是foo & ,而不是foo *

  3. foo::operator[] returns a non-const reference to a temporary, which some compilers might accept, but is just plain wrong. foo::operator[]返回一个对临时对象的非常量引用,一些编译器可能会接受,但这是完全错误的。 (spotted by Ted Lyngmo) (由 Ted Lyngmo 发现)

The following code compiles ( https://godbolt.org/z/_F_ZpJ ):以下代码编译( https://godbolt.org/z/_F_ZpJ ):

#include <iostream>
struct foo;

struct bar
{
    uint32_t *mem;
    uint32_t *opcode;

    bar():mem(nullptr),opcode(nullptr){}
    bar( foo *f, int index );
    bar (bar const &) = default;  // add default copy constructor
    operator bool(){ return (this->mem != nullptr) & (this->opcode != nullptr); }
};


struct foo{

    uint32_t *memory = new uint32_t[16]();
    uint32_t *instructions = new uint32_t[16]();

    foo(){}

    ~foo(){
        delete[] this->memory;
        delete[] this->instructions;
    }

   bar operator[]( int index){
      return bar( this, index%16 ); // this, not *this
   } 

};


bar::bar( foo *f, int index )   // moved the definition down here
{
     this->mem = f->memory + (index%16);
     this->opcode = f->instructions +(index%16);
}

std::ostream& operator<<( std::ostream& os, bar &t )
{
    if( t ){
        return os << "bar:" << (*t.mem) << "\t-\t" << (*t.opcode);
    }else{
        return os << "bar: NOT INITIALIZED";
    }
}


std::ostream& operator<<( std::ostream& os, foo &f )
{
    for( int i =0 ; i < 16; i++ ){
        os << f.memory[i] << "\t" << f.instructions[i] << "\n";
    }
    return os;
}

As I already said, there are some basic design problems and you should think about redesigning this code.正如我已经说过的,存在一些基本的设计问题,您应该考虑重新设计此代码。 Something like the code at this link is better.类似于此链接上的代码的东西更好。 Better yet, ditch foo altogether use the refactoring suggested in TJ Bandrowsky's answer.更好的是,完全抛弃foo使用 TJ Bandrowsky 的回答中建议的重构。

Your bar constructor takes a foo* :您的bar构造函数采用foo*

bar( foo *f, int index )

but you provide a dereferenced foo* in your subscript operator:但是您在下标运算符中提供了一个取消引用的foo*

bar &operator[]( int index) {
    return bar( *this, index%16 );
}

This would make it correct:这将使它正确:

    return bar( this, index%16 );

However : You return a bar& to a local (temporary) object.但是:您将bar&返回到本地(临时)object。 This will immediately be a dangling reference since the temporary object will be destroyed when leaving the function.这将立即成为一个悬空引用,因为临时 object 在离开 function 时将被销毁。

This should get you through that particular problem:这应该可以帮助您解决该特定问题:

bar operator[]( int index) {
    return bar( this, index%16 ); // or return {this, index%16};
}

I'd consider refactoring the thing to something like:我会考虑将事情重构为:

bar {
uint opcode, mem;
}

then make your machine model a std:vector and it would be a lot simpler.然后让你的机器 model 成为 std:vector ,它会简单得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM