C++ Forward declaration and #39;Incomplete type is not allowed#39; error(不允许C++转发声明和#39;不完整的类型#39;错误)
问题描述
我有两个类(或者更好的是,头文件)是我的C++程序的一部分,我就是不能让它们全部工作!他们基本上需要彼此的数据才能正常运行,作为我的应用程序的一部分。不要通过阅读此代码的要点来折磨自己;我只需要解决转发声明和相互包含问题,因此只查看与此问题有关的代码部分。
错误出现在最后的第二个代码片段中(我不得不从第一个代码片段中砍掉一大块代码,这样我才能发布问题,我想这与我的问题无关)。
IntroForm.h
#pragma once
#include <stdlib.h>
#include "creditsForm.h"
#include "registerForm.h"
#include "aboutForm.h"
#include "QuizForm.h"
#include <windows.h>
#include <time.h>
#ifndef __introForm__H__
#define __introForm__H__
namespace InteractiveQuiz {
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    ref class QuizForm;
    /// <summary>
    /// Summary for introForm
    /// </summary>
    public ref class introForm : public System::Windows::Forms::Form
    {
    public:
        introForm(void)
        {
            InitializeComponent();
            //
            //TODO: Add the constructor code here
            //
        }
    protected:
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        ~introForm()
        {
            if (components)
            {
                delete components;
            }
        }
        // Extracts a word from a sentence with a given ordinal number
        string extractWord(int ordinal, string sentence)
        {
            int counter = 0;
            string word;
            for (int i = 0; i < sentence.length(); i++)
            {
                if (sentence[i] == ',')
                {
                    if (sentence [i+1] != ',')
                    {
                        counter ++;
                        if (counter == ordinal)
                        {
                            return word;
                        }
                        word ="";
                    }
                }
                else
                {
                    word += sentence[i];
                }       
            }
        }
private: System::Void btnExit1_Click(System::Object^  sender, System::EventArgs^  e) {
             exit(1);
         }
private: System::Void btnCredits1_Click(System::Object^  sender, System::EventArgs^  e) {
             creditsForm^ credits = gcnew creditsForm;
             credits->Show();
         }
private: System::Void registerBtn_Click(System::Object^  sender, System::EventArgs^  e) {
             registerForm^ registerUser = gcnew registerForm;
             registerUser->Show();
         }
private: System::Void aboutToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e) {
             aboutForm^ aboutApp = gcnew aboutForm;
             aboutApp->Show();
         }
private: System::Void quitToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e) {
             introForm::Close();
         }
private: System::Void introForm_Load(System::Object^  sender, System::EventArgs^  e) {
             ifstream regUsers ("regUsers.csv");
             if (regUsers)
             {
                 lblUser->Enabled = true;
                 lblPass->Enabled = true;
                 logUsername->Enabled = true;
                 logPassword->Enabled = true;
                 btnLogSubmit->Enabled = true;
                 if (lblLogin->Text == L"Not logged in")
                 {
                    quizLogo->Visible = false;
                 }
             }
             else
             {
                 lblUser->Enabled = false;
                 lblPass->Enabled = false;
                 logUsername->Enabled = false;
                 logPassword->Enabled = false;
                 btnLogSubmit->Enabled = false;
                 quizLogo->Visible = true;
             }
             regUsers.close();
         }
public: String^ loggedUser;
private: System::Void btnLogSubmit_Click(System::Object^  sender, System::EventArgs^  e) {
             if (logUsername->Text->Length < 6 && logPassword->Text->Length < 8)
             {
                 errorLabel->Text = L"Username must be at least 6 and password 8 characters long!";
                 errorLabel->Visible = true;
             }
             else if (logUsername->Text->Length < 6)
             {
                 errorLabel->Text = L"Username must be at least 6 characters long!";
                 errorLabel->Visible = true;
             }
             else if (logUsername->Text->Contains(" "))
             {
                 errorLabel->Text = L"Username must not contain spaces!";
                 errorLabel->Visible = true;
             }
             else if (logPassword->Text->Length < 8)
             {
                 errorLabel->Text = L"Password must be at least 8 characters long!";
                 errorLabel->Visible = true;
             }
             if (logUsername->Text->Length >= 6 && logPassword->Text->Length >= 8)
             {
                 String^ result = logUsername->Text + "," + logPassword->Text;
                 string result2 = marshal_as<string>(result);
                 ifstream regUsers("regUsers.csv");
                 string line;
                 string fileUserPass;
                 /* While there is still a line. */
                 while(getline(regUsers, line))
                 {
                     fileUserPass = extractWord(1, line) + "," + extractWord(2,line);
                     if (fileUserPass == result2) // Successful login
                     {
                         lblLogin->Text = L"Logged in as " + logUsername->Text;
                         quizLogo->Visible = true;
                         errorLabel->Visible = false;
                         btnLogout->Enabled = true;
                         startNewToolStripMenuItem->Enabled = true;
                         loggedUser = logUsername->Text;
                     } 
                 }
                 regUsers.close();
                 if (fileUserPass != result2)
                 {
                     errorLabel->Text = L"Username or password incorrect!";
                     errorLabel->Visible = true;
                 }
             }
         }
private: System::Void btnLogout_Click(System::Object^  sender, System::EventArgs^  e) {
             btnLogout->Enabled = false;
             lblLogin->Text = L"Not logged in";
             quizLogo->Visible = false;
             errorLabel->Visible = false;
             logUsername->Clear();
             logPassword->Clear();
             logUsername->Focus();
             startNewToolStripMenuItem->Enabled = false;
         }
private: System::Void startNewToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e) {
             QuizForm^ quiz = gcnew QuizForm;
             quiz->Show();
         }
};
}
#endif // !__introForm__H__
QuizForm.h
#pragma once
#include <string.h>
using namespace std;
#ifndef __QuizForm__H__
#define __QuizForm__H__
namespace InteractiveQuiz {
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    ref class introForm;
    /// <summary>
    /// Summary for QuizForm
    /// </summary>
    public ref class QuizForm : public System::Windows::Forms::Form
    {
    public:
        QuizForm(void)
        {
            InitializeComponent();
            //
            //TODO: Add the constructor code here
            //
        }
    protected:
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        ~QuizForm()
        {
            if (components)
            {
                delete components;
            }
        }
    private: System::Windows::Forms::TabControl^  tabControl;
    protected: 
    protected: 
    private: System::Windows::Forms::TabPage^  tabPage1;
    private: System::Windows::Forms::TabPage^  tabPage2;
    private: System::Windows::Forms::MenuStrip^  menuStrip1;
    private: System::Windows::Forms::Button^  button1;
    private: System::Windows::Forms::ToolStripMenuItem^  quizToolStripMenuItem;
    private: System::Windows::Forms::ToolStripMenuItem^  startNewToolStripMenuItem;
    private: System::Windows::Forms::ToolStripMenuItem^  endQuizToolStripMenuItem;
    private: System::Windows::Forms::ToolStripSeparator^  toolStripSeparator1;
    private: System::Windows::Forms::ToolStripMenuItem^  quitToolStripMenuItem;
    private: System::Windows::Forms::ToolStripMenuItem^  helpToolStripMenuItem;
    private: System::Windows::Forms::ToolStripMenuItem^  aboutToolStripMenuItem;
    private: System::Windows::Forms::Label^  lblQuizLogin;
    private:
        /// <summary>
        /// Required designer variable.
        /// </summary>
        System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        void InitializeComponent(void)
        {
            this->tabControl = (gcnew System::Windows::Forms::TabControl());
            this->tabPage1 = (gcnew System::Windows::Forms::TabPage());
            this->tabPage2 = (gcnew System::Windows::Forms::TabPage());
            this->menuStrip1 = (gcnew System::Windows::Forms::MenuStrip());
            this->quizToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
            this->startNewToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
            this->endQuizToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
            this->toolStripSeparator1 = (gcnew System::Windows::Forms::ToolStripSeparator());
            this->quitToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
            this->helpToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
            this->aboutToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
            this->button1 = (gcnew System::Windows::Forms::Button());
            this->lblQuizLogin = (gcnew System::Windows::Forms::Label());
            this->tabControl->SuspendLayout();
            this->menuStrip1->SuspendLayout();
            this->SuspendLayout();
            // 
            // tabControl
            // 
            this->tabControl->Controls->Add(this->tabPage1);
            this->tabControl->Controls->Add(this->tabPage2);
            this->tabControl->Location = System::Drawing::Point(12, 27);
            this->tabControl->Name = L"tabControl";
            this->tabControl->SelectedIndex = 0;
            this->tabControl->Size = System::Drawing::Size(686, 430);
            this->tabControl->TabIndex = 0;
            // 
            // tabPage1
            // 
            this->tabPage1->Location = System::Drawing::Point(4, 22);
            this->tabPage1->Name = L"tabPage1";
            this->tabPage1->Padding = System::Windows::Forms::Padding(3);
            this->tabPage1->Size = System::Drawing::Size(678, 404);
            this->tabPage1->TabIndex = 0;
            this->tabPage1->Text = L"tabPage1";
            this->tabPage1->UseVisualStyleBackColor = true;
            // 
            // tabPage2
            // 
            this->tabPage2->Location = System::Drawing::Point(4, 22);
            this->tabPage2->Name = L"tabPage2";
            this->tabPage2->Padding = System::Windows::Forms::Padding(3);
            this->tabPage2->Size = System::Drawing::Size(678, 404);
            this->tabPage2->TabIndex = 1;
            this->tabPage2->Text = L"tabPage2";
            this->tabPage2->UseVisualStyleBackColor = true;
            // 
            // menuStrip1
            // 
            this->menuStrip1->Items->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(2) {this->quizToolStripMenuItem, 
                this->helpToolStripMenuItem});
            this->menuStrip1->Location = System::Drawing::Point(0, 0);
            this->menuStrip1->Name = L"menuStrip1";
            this->menuStrip1->Size = System::Drawing::Size(710, 24);
            this->menuStrip1->TabIndex = 1;
            this->menuStrip1->Text = L"menuStrip1";
            // 
            // quizToolStripMenuItem
            // 
            this->quizToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(4) {this->startNewToolStripMenuItem, 
                this->endQuizToolStripMenuItem, this->toolStripSeparator1, this->quitToolStripMenuItem});
            this->quizToolStripMenuItem->Name = L"quizToolStripMenuItem";
            this->quizToolStripMenuItem->Size = System::Drawing::Size(43, 20);
            this->quizToolStripMenuItem->Text = L"&Quiz";
            // 
            // startNewToolStripMenuItem
            // 
            this->startNewToolStripMenuItem->Name = L"startNewToolStripMenuItem";
            this->startNewToolStripMenuItem->Size = System::Drawing::Size(125, 22);
            this->startNewToolStripMenuItem->Text = L"Start &New";
            // 
            // endQuizToolStripMenuItem
            // 
            this->endQuizToolStripMenuItem->Name = L"endQuizToolStripMenuItem";
            this->endQuizToolStripMenuItem->Size = System::Drawing::Size(125, 22);
            this->endQuizToolStripMenuItem->Text = L"&End Quiz";
            // 
            // toolStripSeparator1
            // 
            this->toolStripSeparator1->Name = L"toolStripSeparator1";
            this->toolStripSeparator1->Size = System::Drawing::Size(122, 6);
            // 
            // quitToolStripMenuItem
            // 
            this->quitToolStripMenuItem->Name = L"quitToolStripMenuItem";
            this->quitToolStripMenuItem->Size = System::Drawing::Size(125, 22);
            this->quitToolStripMenuItem->Text = L"Q&uit";
            // 
            // helpToolStripMenuItem
            // 
            this->helpToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(1) {this->aboutToolStripMenuItem});
            this->helpToolStripMenuItem->Name = L"helpToolStripMenuItem";
            this->helpToolStripMenuItem->Size = System::Drawing::Size(44, 20);
            this->helpToolStripMenuItem->Text = L"&Help";
            // 
            // aboutToolStripMenuItem
            // 
            this->aboutToolStripMenuItem->Name = L"aboutToolStripMenuItem";
            this->aboutToolStripMenuItem->Size = System::Drawing::Size(116, 22);
            this->aboutToolStripMenuItem->Text = L"&About...";
            // 
            // button1
            // 
            this->button1->Location = System::Drawing::Point(623, 476);
            this->button1->Name = L"button1";
            this->button1->Size = System::Drawing::Size(75, 23);
            this->button1->TabIndex = 2;
            this->button1->Text = L"Close";
            this->button1->UseVisualStyleBackColor = true;
            // 
            // lblQuizLogin
            // 
            this->lblQuizLogin->AutoSize = true;
            this->lblQuizLogin->Location = System::Drawing::Point(12, 489);
            this->lblQuizLogin->Name = L"lblQuizLogin";
            this->lblQuizLogin->Size = System::Drawing::Size(70, 13);
            this->lblQuizLogin->TabIndex = 3;
            this->lblQuizLogin->Text = L"Not logged in";
            // 
            // QuizForm
            // 
            this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            this->ClientSize = System::Drawing::Size(710, 511);
            this->Controls->Add(this->lblQuizLogin);
            this->Controls->Add(this->button1);
            this->Controls->Add(this->tabControl);
            this->Controls->Add(this->menuStrip1);
            this->MainMenuStrip = this->menuStrip1;
            this->MaximizeBox = false;
            this->MinimizeBox = false;
            this->Name = L"QuizForm";
            this->StartPosition = System::Windows::Forms::FormStartPosition::CenterScreen;
            this->Text = L"Interactive Quiz";
            this->Load += gcnew System::EventHandler(this, &QuizForm::QuizForm_Load);
            this->tabControl->ResumeLayout(false);
            this->menuStrip1->ResumeLayout(false);
            this->menuStrip1->PerformLayout();
            this->ResumeLayout(false);
            this->PerformLayout();
        }
#pragma endregion
private: System::Void QuizForm_Load(System::Object^  sender, System::EventArgs^  e) {
             introForm^ intro = gcnew introForm; // the second introForm in this line is underlined with the mentioned error
         }
    };
}
#endif // !__QuizForm__H__
你在这两段代码中看到的是我在网上找到的拼图拼图,哈哈。:)
我的目标:能够在QuizForm内部使用IntroForm中的变量。
提前谢谢! 鲍里斯·J
推荐答案
在C++中使用对象的正向声明时,请记住几点。
- 您不能分配不完整的类型,因为编译器还不知道它有多大。只需使用指向不完整类型的指针即可解决此问题。
- 在编译器看到不完整类型的定义之前,不能引用该类型的成员。这可以通过将接口和实现分离到头文件和代码文件来解决。
- 如果您处于必须使用不完整类型的情况,则您可能做错了什么。尽可能避免循环引用。
关于您的评论:
当您有一个类的正向声明时,比如class foo;,它被称为不完整类型,因为定义还不存在。您可以通过指针(如foo *bar;)间接引用它,但不能在任何需要了解其内部知识的操作中使用它,例如取消引用它、使用它包含的函数等。您可以完整声明一个类,尽管使用的是函数原型而不是函数。然后,您可以在另一个文件中定义函数。这将允许您完全定义循环依赖,而不会造成任何破坏。
例如:
On codepad with the headers inline-included.
单个文件:
foo.h:
#ifndef __FOO_H_INCLUDE
    #define __FOO_H_INCLUDE
    #ifndef __FOO_H_DEFINED
        #define __FOO_H_DEFINED
        class foo;
        #include "bar.h"
    #endif
    class foo{
        bar *a;
        int b;
        public:
        foo( int _b );
        bar& getbar();
        int getb();
        void setbar( bar* _a );
    };
#endif
bar.h:
#ifndef __BAR_H_INCLUDE
    #define __BAR_H_INCLUDE
    #ifndef __BAR_H_DEFINED
        #define __BAR_H_DEFINED
        class bar;
        #include "foo.h"
    #endif
    class bar{
        foo *a;
        int b;
        public:
        bar(int _b );
        foo& getfoo();
        int getb();
        void setfoo( foo* _a );
    };
#endif
main.cpp:
#include<iostream>
#include "foo.h"
#include "bar.h"
foo::foo( int _b ){ b = _b;}
int foo::getb(){ return b; }
bar& foo::getbar(){ return *a; }
void foo::setbar( bar* _a){ a = _a; }
bar::bar( int _b ){ b = _b;}
int bar::getb(){ return b; }
foo& bar::getfoo(){ return *a; }
void bar::setfoo( foo* _a ){ a = _a; }
int main(){
    foo a(5);
    bar b(20);
    a.setbar(&b);
    b.setfoo(&a);
    std::cout   << a.getbar().getfoo().getbar().getb() 
                << "
" 
                << a.getbar().getfoo().getbar().getfoo().getb();
    return 0;
}
这篇关于不允许C++转发声明和';不完整的类型';错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:不允许C++转发声明和';不完整的类型';错误
 
				
         
 
            
        基础教程推荐
- 如何通过C程序打开命令提示符Cmd 2022-12-09
- 常量变量在标题中不起作用 2021-01-01
- 如何在 C++ 中初始化静态常量成员? 2022-01-01
- 这个宏可以转换成函数吗? 2022-01-01
- 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
- 如何检查GTK+3.0中的小部件类型? 2022-11-30
- 在 C++ 中计算滚动/移动平均值 2021-01-01
- C++结构和函数声明。为什么它不能编译? 2022-11-07
- 我有静态或动态 boost 库吗? 2021-01-01
 
    	 
    	 
    	 
    	 
    	 
    	 
    	 
    	 
						 
						 
						 
						 
						 
				 
				 
				 
				